Initial commit
authorGraydon, Tracy <tracy.graydon@intel.com>
Mon, 22 Apr 2013 18:58:15 +0000 (11:58 -0700)
committerGraydon, Tracy <tracy.graydon@intel.com>
Mon, 22 Apr 2013 18:58:15 +0000 (11:58 -0700)
100 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
COPYING.LIB [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Examples/ckbook.b [new file with mode: 0644]
Examples/pi.b [new file with mode: 0644]
Examples/primes.b [new file with mode: 0644]
Examples/twins.b [new file with mode: 0644]
FAQ [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
Test/BUG.bc [new file with mode: 0644]
Test/array.b [new file with mode: 0644]
Test/arrayp.b [new file with mode: 0644]
Test/aryprm.b [new file with mode: 0644]
Test/atan.b [new file with mode: 0644]
Test/checklib.b [new file with mode: 0644]
Test/div.b [new file with mode: 0644]
Test/exp.b [new file with mode: 0644]
Test/fact.b [new file with mode: 0644]
Test/jn.b [new file with mode: 0644]
Test/ln.b [new file with mode: 0644]
Test/mul.b [new file with mode: 0644]
Test/raise.b [new file with mode: 0644]
Test/signum [new file with mode: 0644]
Test/sine.b [new file with mode: 0644]
Test/sqrt.b [new file with mode: 0644]
Test/sqrt1.b [new file with mode: 0644]
Test/sqrt2.b [new file with mode: 0644]
Test/testfn.b [new file with mode: 0644]
Test/timetest [new file with mode: 0755]
aclocal.m4 [new file with mode: 0644]
bc/Makefile.am [new file with mode: 0644]
bc/Makefile.in [new file with mode: 0644]
bc/bc.c [new file with mode: 0644]
bc/bc.h [new file with mode: 0644]
bc/bc.y [new file with mode: 0644]
bc/bcdefs.h [new file with mode: 0644]
bc/const.h [new file with mode: 0644]
bc/execute.c [new file with mode: 0644]
bc/fix-libmath_h [new file with mode: 0755]
bc/global.c [new file with mode: 0644]
bc/global.h [new file with mode: 0644]
bc/libmath.b [new file with mode: 0644]
bc/libmath.h [new file with mode: 0644]
bc/load.c [new file with mode: 0644]
bc/main.c [new file with mode: 0644]
bc/proto.h [new file with mode: 0644]
bc/sbc.y [new file with mode: 0644]
bc/scan.c [new file with mode: 0644]
bc/scan.l [new file with mode: 0644]
bc/storage.c [new file with mode: 0644]
bc/util.c [new file with mode: 0644]
bc/warranty.c [new file with mode: 0644]
config.h.in [new file with mode: 0644]
configure [new file with mode: 0755]
configure.in [new file with mode: 0644]
dc/Makefile.am [new file with mode: 0644]
dc/Makefile.in [new file with mode: 0644]
dc/TODO [new file with mode: 0644]
dc/array.c [new file with mode: 0644]
dc/dc-proto.h [new file with mode: 0644]
dc/dc-regdef.h [new file with mode: 0644]
dc/dc.c [new file with mode: 0644]
dc/dc.h [new file with mode: 0644]
dc/eval.c [new file with mode: 0644]
dc/misc.c [new file with mode: 0644]
dc/numeric.c [new file with mode: 0644]
dc/stack.c [new file with mode: 0644]
dc/string.c [new file with mode: 0644]
depcomp [new file with mode: 0755]
doc/Makefile.am [new file with mode: 0644]
doc/Makefile.in [new file with mode: 0644]
doc/bc.1 [new file with mode: 0644]
doc/bc.info [new file with mode: 0644]
doc/bc.texi [new file with mode: 0644]
doc/dc.1 [new file with mode: 0644]
doc/dc.info [new file with mode: 0644]
doc/dc.texi [new file with mode: 0644]
doc/texi-ver.incl.in [new file with mode: 0644]
doc/texinfo.tex [new file with mode: 0644]
h/getopt.h [new file with mode: 0644]
h/number.h [new file with mode: 0644]
install-sh [new file with mode: 0755]
lib/Makefile.am [new file with mode: 0644]
lib/Makefile.in [new file with mode: 0644]
lib/getopt.c [new file with mode: 0644]
lib/getopt1.c [new file with mode: 0644]
lib/number.c [new file with mode: 0644]
lib/testmul.c [new file with mode: 0644]
lib/vfprintf.c [new file with mode: 0644]
missing [new file with mode: 0755]
packaging/bc-1.06-dc_ibase.patch [new file with mode: 0644]
packaging/bc-1.06.95-matlib.patch [new file with mode: 0644]
packaging/bc-1.06.95-memleak.patch [new file with mode: 0644]
packaging/bc-1.06.95-sigintmasking.patch [new file with mode: 0644]
packaging/bc.spec [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..5a80f64
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,6 @@
+Phil Nelson <philnelson@acm.org> wrote bc, including the number.c
+source in the "lib" directory.
+
+Ken Pizzini <ken@gnu.org> wrote dc, making use of the lib/number.c
+code that Phil Nelson wrote to handle the actual multiprecision
+arithmetic.
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..b52b59e
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of 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 show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+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.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+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
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+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.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+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
+           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 the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <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 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St., Fifth Floor, Boston, MA 02110-1301  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) year  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 is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/COPYING.LIB b/COPYING.LIB
new file mode 100644 (file)
index 0000000..f5cc5aa
--- /dev/null
@@ -0,0 +1,516 @@
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+^L
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+^L
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  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.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+^L
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+^L
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+^L
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+^L
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+^L
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+^L
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.
+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 library's name and a brief idea of what it
+does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc.  51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301  USA
+
+Also add information on how to contact you by electronic and paper
+mail.
+
+You should also get your employer (if you work as a programmer) or
+your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James
+Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..562bba5
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,1341 @@
+Mon Sep  4 19:27:49 2006 Ken Pizzini <ken@gnu.org>
+       * configure.in: re-factor how version numbers are handled; add errno.h
+         and strtol() checks; add doc-texi-ver.incl output
+       * bc/bcdefs.h: Prefer <string.h> over <strings.h>
+       * bc/execute.c, bc/load.c, bc/main.c, bc/proto.h, bc/scan.l,
+         bc/storage.c, bc/util.c, bc/warranty.c: De-lint some with "const"
+         declarations, "static" declarations, and un-shadowing a few global
+         variables and functions
+       * dc/dc.c: add "static" keyword on flush_okay() function declaration,
+         just for good hygene
+       * dc/numeric.c: Reworked to avoid breaking C99 type-punning rules
+
+Wed Jun 14 08:21:17 2006 Ken Pizzini <ken@gnu.org>
+       * dc/numeric.c (dc_int2data): rework code so that C99 compilers
+         stop whining about the type punning
+       * dc/dc.c (flush_okay): add "static" keyword as a matter of good
+         coding hygene
+
+Sun Jun 11 21:40:37 2006 Ken Pizzini <ken@gnu.org>
+       * doc/bc.1: strip release version information which is not being
+         automatically kept up-to-date
+       * doc/dc.1: don't capitalize Dc or DC
+
+Sun Jun 11 09:07:26 2006 Ken Pizzini <ken@gnu.org>
+       * doc/bc.texi, doc/dc.texi, doc/texi-ver.incl.in, doc/Makefile.am:
+         make version text in texinfo-based documentation auto-derive from
+         configure.in
+       * configure.in: update to use more modern automake/autoconf
+         directives; factor out version numbers so that AC_SUBST and
+         AC_OUTPUT kcan be used to create doc/texi-ver.incl
+       * doc/Makefile.am: automake does (now) have a mechanism to
+         auto-include declared man pages in the dist tarball, so
+         remove FIXME block
+
+Sun Jun 11 03:04:18 2006 Ken Pizzini <ken@gnu.org>
+       * lib/Makefile.am: testmul, specialnumber, multidigits.h are
+         autogenerated by special request (only), and "make clean" should
+         remove them
+       * lib/testmul.c: CLOCKS_PER_SEC is typically a "long" value, so make
+         test_time wide enough to hold it; add missing #include directives
+       * lib/number.c: silly warning clean-up:
+         + declare rt_warn() and rt_error() to take a CONST char* first
+           argument
+         + neither _bc_rec_mul() nor _bc_simp_mul() use the full_scale
+           argument, so remove it in the function definitions and invocations
+         + some C libraries define an index() function; use a different index
+           variable name to avoid gratuitous namespace shadowing
+
+Sun Jun  4 13:56:58 2006 Ken Pizzini <ken@gnu.org>
+       * doc/dc.texi: document new DC_LINE_LENGTH variable; mention
+         traditional dc's handling of P with a numeric input
+       * dc/dc.c (flush_okay, main): make code detecting and handling
+         write errors cleaner
+
+Sun Jun  4 12:26:00 2006 Phil Nelson <phil@cs.wwu.edu>
+       * bc/main.c: Make sure 3 is the minimum line length.
+       * doc/bc.1, doc/bc.texi: Document the BC_LINE_LENGTH of 0 feature.
+
+Sun Jun  4 04:41:28 2006 Ken Pizzini <ken@gnu.org>
+       * dc/dc.c (main): fflush() isn't enough: also check that fclose()
+         does not return an error before exiting with EXIT_SUCCESS
+
+Sun Jun  4 04:15:15 2006 Ken Pizzini <ken@gnu.org>
+       * dc/dc.c, dc/eval.c: detect, report (if possible), and exit with error
+         if any I/O errors are encountered
+
+Sun Jun  4 02:27:41 2006 Ken Pizzini <ken@gnu.org>
+       * bc/main.c, bc/util.c: allow a BC_LINE_LENGTH of zero as a
+         special-case, meaning "don't ever wrap lines"
+       * dc/numeric.c, configure.in: add support for a DC_LINE_LENGTH
+         variable, with a value of zero meaning "don't ever wrap lines"
+
+Fri May  5 18:45:17 2006 Ken Pizzini <ken@gnu.org>
+       * dc/dc.c (try_file): S_ISREG() test was inverted! :-(
+         (how very embarrassing)
+
+       * configure.in: the "if test" -> "case" conversion in the last commit
+         translated the handling of flex incorrectly; fixed
+
+       * src/scan.l: readline versions 4.2 and up give their own prototype
+         for readline() in readline.h, which conflicts with the one that is
+         in scan.l, so just do without the prototype in scan.l (if someone
+         needs to backport to a very old version of readline, they should be
+         able to handle adding the prototype back in themselves)
+
+       * doc/bc.texi: use of @var{} in @item causes capitalization on output,
+         which is wrong, and furthermore the use of @var{} for e() and j() is
+         also inconsistent with how the other math functions are formatted
+
+Sat Apr 29 05:02:15 2006 Ken Pizzini <ken@gnu.org>
+       * configure.in: The "true" branch of AC_ARG_WITH needed to
+         be conditionalized on the value of $withval (thanks to Mike
+         Frysinger of Gentoo for pointing this out); prefer using
+         "case" over "if test" in shell string-match conditionals;
+         make use of AC_HELP_STRING; added copyright block; clean
+         out old "dnl"'d directives
+
+Sat Apr 29 04:02:23 2006 Ken Pizzini <ken@gnu.org>
+       * dc/dc.c (try_file): fix typo in S_ISFIFO conditional
+
+       * doc/bc.1, doc/bc.texi, doc/dc.1, doc/dc.texi: make some
+         formatting clean-up (minor)
+
+Wed Apr 26 15:38:32 2006 Ken Pizzini <ken@gnu.org>
+       * dc/dc.c (try_file): rework special-file detection so that
+         friendlier error messages can be given for the most common
+         error of this class (i.e., the "dc directory" typo).
+
+Thu Apr 20 17:45:46 2006 Ken Pizzini <ken@gnu.org>
+       * configure.in: Newer versions of flex (such as ver. 2.5.33)
+         don't seem to like an argument of "-I8" anymore ("option `I'
+         doesn't allow an argument"), so split that into "-I -8".
+
+Wed Mar 29 05:09:14 2006 Ken Pizzini <ken@gnu.org>
+       * dc/string.c, dc/misc.c, dc/stack.c, dc/dc.c, dc/eval.c, dc/array.c:
+         Make splint (http://www.splint.org/) happier by making all
+         comparisons to 0 and NULL explicit, and adding some explicit casts
+         that aren't strictly necessary.  (But I'm omitting from this commit
+         various splint annotations that just serve to make the code ugly.)
+
+Tue Mar 28 13:36:00 2006 Phil Nelson <phil@cs.wwu.edu>
+       * bc/util.c: Move code so size checks are before use.
+
+       * doc/bc.1: Quote .IP argument.
+
+Tue Mar 28 12:09:38 2006 Ken Pizzini <ken@gnu.org>
+       * dc/dc.c (try_file):  Added file type detection to ignore some
+         special files (particularly directories and block files), because
+         several people have asked that a typo for "cd" not fail silently.
+
+       * configure.in: add detection of fstat() to determine how the
+         above detection should be implemented.
+
+Wed Mar 15 9:50:00 2006 Phil Nelson <phil@cs.wwu.edu>
+       * lib/getopt.c:  Added a define to disable/enable
+         gettext support.  May need to be deleted later
+         when gettext is fully supported.  
+
+Mon Mar 13 13:57:00 2006 Phil Nelson <phil@cs.wwu.edu>
+       * bc/bc.y: Remove second call to lookup() in a rule.
+         Removes a free'd twice bug.
+
+Sat May 28 05:42:01 2005 Ken Pizzini <ken@gnu.org>
+
+       * doc/dc.1, doc/dc.texi: add verbage about the need to use
+         upper-case letters for ibase>10 (bug reported by "TJIC").
+
+Fri May 20 ??:??:?? 2005 Ken Pizzini <ken@gnu.org>
+       * lib/getopt.c, lib/getopt1.c: Update to more recent versions.
+
+Fri May 27 09:19:21 2005 Ken Pizzini <ken@gnu.org>
+
+       * dc/eval.c: abstract out skip_past_eol() function to handle comments
+
+Fri May 27 07:30:52 2005 Ken Pizzini <ken@gnu.org>
+
+       * dc/numeric.c (dc_numlen), doc/dc.1, dc.texi: correct Z command
+         to match historical meaning
+
+Fri May 27 06:54:19 2005 Ken Pizzini <ken@gnu.org>
+
+       * dc/eval.c: ignore trailing comments in tail-recursion detection
+
+       * dc/eval.c, doc/dc.texi: finally fix dc to trap interrupts,
+         aborting pending macros but not exiting
+
+Fri May 27 03:37:30 2005 Ken Pizzini <ken@gnu.org>
+
+       * dc/numeric.c: Address Debian bug #221781: values exceeding
+         a C "long" don't play well with k/i/o/a/Q/:/; commands.
+         Adding a diagnostic, and returning a "more bogus" value than
+         zero, for this situation.
+
+Thu May 26 09:03:57 2005 Ken Pizzini <ken@gnu.org>
+
+       * dc/eval.c:
+         1) fix tail recursion to also work for 'x' and '?' commands
+         2) fix tail recursion to ignore trailing spaces in the current
+            invocation string when determining if tail recursion is
+            appropriate
+         3) remove a couple of misleading and/or meaningless comments
+         4) add documentation for stdin_lookahead, since the code is far
+            from transparent about its purpose and usage
+         5) simplify ibase conditional by rearranging branches
+
+Wed May 25 21:20:08 2005 Ken Pizzini <ken@gnu.org>
+
+       * dc/array.c dc/dc-proto.h dc/dc-regdef.h dc/dc.c dc/dc.h
+         dc/eval.c dc/numeric.c: whitespace cleanup
+
+Wed May 25 19:48:26 2005 Ken Pizzini <ken@gnu.org>
+
+       * COPYING COPYING.LIB dc/dc-proto.h dc/dc-regdef.h dc/dc.h
+         dc/array.c dc/dc.c dc/eval.c dc/misc.c dc/numeric.c dc/stack.c
+         dc/string.c doc/dc.1 doc/dc.texi:
+         update FSF address in copyright notices
+
+Wed May 25 19:39:46 2005 Ken Pizzini <ken@gnu.org>
+
+       * dc/stack.c: If a register is used for an array, its corresponding
+         stack could be auto-created in the DC_UNINITIALIZED state; handle
+         this situation gracefully.  Thanks to Ben Collerson
+         (http://bur.st/~benc/) for the bug report.
+
+Wed Dec 31 07:26:00 2003 Phil Nelson  <phil@cs.wwu.edu>
+
+       * Makefile.am: add depcomp
+
+       * {bc,dc,lib}/Makefile.am: CFLAGS -> AM_CFLAGS, YFLAGS -> AM_YFLAGS
+
+       * bc/*: consistent copyright
+
+Fri May  9 21:52:46 2003 Ken Pizzini <ken@gnu.org>
+
+       * dc/dc-proto.h dc/dc.c dc/eval.c: add tail-recursion optimization
+
+       * dc/numeric.c: clean up handling of conditional includes/defines;
+         editorial fix to comment; trivial (indentation, mostly) clean-up of
+         out_char() function [gratuitious; commit was accidental and I'm
+         adding this note to a replacement log message]
+
+       * dc/misc.c: fixed spelling and grammatical errors in comment
+
+       * dc/dc-regdef.h: simplify the handling of UCHAR_MAX/DC_REGCOUNT
+         defaults
+
+Thu Apr 17 16:25:35 2003 Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/{execute.c, proto.h, util.c}: char -> int in a few
+         places dealing with isdigit and getchar(), updated copyright 
+
+       * bc/main.c: minor formatting changes, updated copyright
+
+       * bc/libmath.b, doc/{bc.1,bc.texi}: updated copyright
+
+Mon Mar 31 22:19:00 2003  Phil Nelson  <phil@cs.wwu.edu>
+
+       * doc/{bc.1,bc.texi} Fix a couple of typos.
+       * bc/main.c: exit value changed when exiting from interrupt.
+
+Tue Mar 4 09:38:00 2003  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/libmath.b: Add one level recursion to each function to
+         get ibase set to 10 (decimal) if called with other ibases.
+
+Mon Nov 11 09:15:00 2002  Phil Nelson  <phil@cs.wwu.edu>
+
+       * doc/{bc.1,bc.texi} Fix documentation about array parameters.
+
+Tue Mar 19 11:22:06 2002  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/{bc.y,bcdefs.h,scan.l}: Add void functions.
+       * doc/{bc.1,bc.texi}:  Document void functions.
+       * bc/util.c:  Fix bug in AVL routines.
+
+Wed May 23 08:40:00 2001  Phil Nelson  <phil@cs.wwu.edu>
+
+       * Makefile.am, */Makefile.am, configure.in: Add gcc specific
+         flags only if using gcc.
+       * bc/{bc.y,sbc.y,bcdefs.h,const.h,execute.c,global.[ch],proto.h, 
+             main.c,util.c}:  Removal of buffer overflow, new extern
+         and initialization code. New dynamic buffer manipulation.
+       * bc/load.c: correct char extraction.
+       * bc/storage.c: correct expansion of variables and arrays.
+
+Sun May 13 19:29:43 2001 Ken Pizzini <ken@gnu.org>
+
+       * dc/array.c: minor optimization: stop scanning array entry indicies
+         if we step beyond the target index
+
+Sun May 13 19:09:31 2001 Ken Pizzini <ken@gnu.org>
+
+       * dc/dc.c: traditional dc implementations drop into reading stdin
+         after processing command-line files; defer to tradition
+
+Sat Feb 17 22:41:14 2001  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/{main.c} Add case 0 for long options that set variables.
+         Correct spelling in usage statement.
+
+Mon Jan 22 18:33:43 2001  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/main.c: Make sure signal code doesn't stomp on errno.
+       * bc/load.c: Make save_addr in load_code() static since it
+         is now possible to call load_code() multiple times in a single
+         function.
+
+Fri Jan 19 10:33:13 2001  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/{main.c,execute.c}: Don't use stdio calls in signal
+         handlers.  Call write directly and move code.
+
+Wed Jan 10 11:33:51 2001  Phil Nelson  <phil@cs.wwu.edu>
+
+       * lib/getopt.c: Include string.h if available.
+         lib/number.c: (bcmath change) Include string.h if available.
+
+Wed Sep 27 17:19:48 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * doc/bc.texi: Added new file. Mainly translated from bc.1
+                      by Brian Youmans.
+         doc/bc.1: Minor changes made as part of reviewing bc.texi.
+
+Wed Sep 20 11:45:00 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/bc.y:  Added a comment on the meanings of lvals.
+
+Wed Sep 13 11:40:24 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/main.c: add --interactive to long options.
+         bc/bc.1: add -i/--interactive to doc.
+         MANY: Update FSF address and Phil's e-mail.
+       
+Tue Sep 12 13:58:16 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * NEWS: update for recent changes.
+         bc/bc.y: remove required parens around return expression.
+         doc/bc.1: update for recent changes.
+
+Fri Sep  8 10:20:01 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/Makefile.am, dc/Makefile.am, lib/Makefile.am:
+           Compile with unsigned characters.
+         bc/main.c: Add --help option.
+         bc/scan.l: Print illegal, non-printable characters in octal.
+
+Fri Sep  8 09:36:54 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/bc.y: Allow more newlines in function definitions.
+         bc/proto.h: Don't prototype main.
+
+Fri Sep  1 16:09:50 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/bc.y: Spelling correction
+         bc/execute.c: Correct expressions for multi-byte names.
+         bc/load.c: Add parens for correct casting.
+         doc/bc.1: Typos.
+         Above fixes pointed out by kwzh@gnu.org (Karl Heuer).
+
+Tue Aug 29 23:03:30 PDT 2000 Phil Nelson  <phil@cs.wwu.edu>
+
+       * lib/testmul.c: #ifdef out a declaration matching #ifdef out
+         code.
+
+Mon Jul 31 07:01:42 2000 Ken Pizzini <ken@gnu.org>
+
+       * dc/numeric.c: use of the "n" command can cause a number to be printed
+         without a trailing newline, which would cause the column counter to
+         fail to be reset and result in inappropriately wrapped numeric outputs.
+         Fixed by always clearing the column counter before outputting each number.
+
+       * dc/stack.c: if a stack is used without ever using the correspondingly
+         named register, it is perfectly legitimate for the register to be
+         uninitialized; added an "else if" to handle this case without aborting.
+
+       * dc/eval.c: updated the comment explaining the restrictions
+         on the | command to better reflect reality.
+
+       * doc/dc.texi: update the FSF office address in the copyright notice
+
+Thu Jul 13 18:13:00 2000 Phil Nelson  <phil@cs.wwu.edu>
+
+       * README: note --with-libedit configure parameter.
+
+Tue Jun 20 22:52:10 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/bcdefs.h: Include <readline/history.h> to quiet warnings. 
+
+       * configure.in: make --with-readline and --with-libedit work correctly.
+
+       * Makefile.am: use $(MAKE) instead of directly calling make.
+
+       * lib/testmul.c: Update to use bc_ on all number.c routines.
+
+Sat Jun 10 22:44:29 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/Makefile.am: Add scan.c to maintainer-clean target.
+
+       * acconfig.h configure.in stamp-h.in bc/Makefile.am bc/execute.c
+         bc/fix-libmath_h bc/global.c bc/load.c bc/main.c bc/storage.c:
+           Remove long string for libmath.  Clean up for compiler errors.
+
+       * dc/numeric.c: Correct parameter name.
+
+Wed May 10 15:51:16 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * {bc,doc,dc,lib}/Makefile.am: Add Makefile.in to maintainer-clean.
+
+       * bootstrap.sh: Added script to run the auto* tools.
+
+       * Imported all into CVS tree.
+
+Sun 2000-05-07  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/Makefile.am, dc/Makefile.am, lib/Makefile.am: Add -Wall to CFLAGS.
+
+       * bc/{execute.c,proto.h,storage.c,util.c}, dc/numeric.c: Changes for
+         -Wall and for name changes in lib/number.c.  (Added bc_ to several
+         routine.  Updated copyright notice.)
+
+       * h/number.h, lib/number.c:  Now comes from bcmath library which is  
+         distributed in a different place. 
+
+Wed Mar 29 17:47:34 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/{bc.y,bcdefs.h,global.h,main.c,proto.h,scan.l,storage.c}:
+         Added BSD libedit support.  Generic support for both where possible.
+         Fixed bugs in readline support noticed during libedit addition.
+         Works with NetBSD-1.4.1 libedit.
+       * doc/bc.1: Documented libedit addition.
+
+Wed Mar 29 10:20:18 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * FAQ: Added this file.
+       * Makfile.am: Added FAQ to distribution
+
+Tue Mar 28 13:52:35 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * lib/number.c, h/number.h: Moved definitions so 
+         number.c/number.h is a stand-alone "library".
+         Changed definition of out_num to not reference a global.
+       * lib/testmul.c: updated #includes for number.h changes.
+       * h/{bcdefs.h,const.h,global.h,proto.h} moved to
+         bc where they really belong.
+       * bc/execute.c: Changed calls to out_num for correctness.
+       * dc/numeric.c: Changed calls to out_num for correctness,
+         include only number.h now and not all the other junk.
+       * configure.in, acconfig.h: Start of support for BSD libedit,
+         added --with-pkg for NetBSD /usr/pkg tree.
+
+Tue Mar 28 11:20:00 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * Test/{exp.b,fact.b,jn.b,mul.b,raise.b}: Tweeks on the tests
+         run to do more computation and test the recursive multiply.
+       * bc/scan.l: Removed a printf('\r') that was unneeded.
+
+Mon Mar 27 14:00:00 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * NEWS: Updated for 1.06.
+       * lib/number.c, h/number.h: Fixed bugs in recursive multiply.
+               Changed these files to be under the LGPL.
+       * Tests/jn.b: Added more tests.
+       * lib/Makefile.am: Only generate a timed version of number.o if
+               requested.
+       * README: Updated with information on how to generate a timed
+               version of number.o.
+       * h/version.h: Updated copyright and version number for dc.
+
+Thu Mar 16 14:01:45 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * doc/bc.1, doc/dc.1, doc/dc.texi: Changed bug reporting address
+         to bug-bc@gnu.org to update with what we hope will be reality.
+
+Tue Feb  8 08:54:19 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * doc/bc.1, bc/util.c: Removed "multiply digits"
+         limit due to new recursive algorithm that doesn't
+         have those limits.
+
+Tue Feb  8 08:47:05 2000  Phil Nelson  <phil@cs.wwu.edu>
+
+       * lib/Makefile.am, lib/testmul.c, lib/number.c, Makefile.am:
+         Finally got a resonable version of the program
+         to test the crossover between non-recursive and
+         recursive multiply algorithms.  Added to distribution
+         and build process.  Does increase build time by 
+         about 10 minutes.
+
+Wed Oct  6 13:28:59 1999  Phil Nelson  <phil@cs.wwu.edu>
+
+       * lib/Makefile.am: Added rules to allow DEFSADD definitions.
+
+Sat Oct  2 19:59:51 1999  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/libmath.b: Correctly do the cosine accuracy.
+
+Fri Oct  1 12:41:51 1999  Phil Nelson  <phil@cs.wwu.edu>
+
+       * lib/number.c: Increase accuracy of computing raise.
+         Also turn off use of recursive multiply routines
+         until furthur testing.
+       * bc/libmath.b: Increase accuracy of cosine.
+       * bc/Makefile.am: Remove -lfl from items to make.
+
+Wed Jul 28 10:29:28 1999  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/scan.l:  rl_len from char to int.  (From FreeBSD
+         bug tracking system and Nick Hibma <nick.hibma@jrc.it>)
+
+Tue Jun 22 08:00:28 1999  Phil Nelson  <phil@cs.wwu.edu>
+
+       * lib/number.c: Rewrote bc_multiply to use a faster
+         algorithm.  Old code not removed yet.
+
+Mon Jun 21 03:08:02 1999  Phil Nelson  <phil@cs.wwu.edu>
+
+       * h/version.h: Updated version number to 1.06.
+         bc/bc.y: Corrected bug in for statement, not popping.
+         bc/execute.c: Improved stack dump/instruction tracing.
+
+Tue Jun 15 22:30:42 1999  Phil Nelson  <phil@cs.wwu.edu>
+
+       * configure.in: Updated bc version to 1.06.
+
+Tue Jun 15 22:27:44 1999  Phil Nelson  <phil@cs.wwu.edu>
+
+       * h/bcdefs.h, h/const.h, bc/execute.c, bc/load.c, bc/storage.c,
+         bc/util.c: Removed segmented function storaged.  Now
+         dynamically expands (by doubling, starting at 1024 bytes)
+         to allow arbitrary sized functions.
+
+Thu Jun 10 22:33:44 1999  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/libmath.b: change scaling in computation of j(n,x) so
+         it correctly computes the value.
+
+Wed Jun 10 10:10:10 1998 Release of bc-1.05a.
+
+Fri Apr 17 10:40:59 1998  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/main.c: Enable readline only if interactive.
+
+Thu Apr 16 16:49:22 1998  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/configure.in: Tweeking of AM_PROG_LEX and associated 
+         special case goo for solaris.
+
+Sat Mar 28 21:43:18 1998  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/Makefile.am: Added "YFLAGS = -d" to get bc.h to build properly.
+
+Mon Mar  9 12:54:42 PST 1998  Ken Pizzini <ken@halcyon.com>
+
+       * doc/dc.texi, doc/dc.1: correct some documentation bugs.
+
+Sun Mar  8 23:56:24 PST 1998  Ken Pizzini <ken@halcyon.com>
+
+       * dc/numeric.c: eliminate superfluous variable from dc_dump_num();
+         annotate unused parameters in dc_add() and dc_sub().
+
+       * h/version.h: change dc version number to 1.2 for release.
+
+Sun Mar  8 21:13:50 1998  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/main.c: Applied patch from Ken Pizzini to force line
+         mode buffering on stdout.
+
+Tue Jan  6 09:15:04 PST 1998  Ken Pizzini <ken@halcyon.com>
+
+       * h/version.h: dc is now up to version 1.1.5.
+
+       * dc/eval.c, dc/numeric.c, doc/dc.texi, doc/dc.1: once again
+         changed the behavior of the 'P' command with a numeric argument
+         to make it more general.  It now dumps out the *whole* number
+         (or rather, the whole of its positive integer portion) as a
+         byte stream.  (For small values this is still the same as 'aP'.)
+
+       * dc/dc-proto.h, dc/dc.h, dc/eval.c, dc/misc.c, dc/numeric.c,
+         dc/stack.c, dc/string.c: Changed most uses of dc_boolean to
+         either dc_discard or dc_newline, and instances of DC_TRUE and
+         DC_FALSE to appropriate instances of DC_TOSS, DC_KEEP, DC_NONL,
+         or DC_WITHNL so that the code self-documents a little better.
+
+Sun Jan  4 15:39:46 PST 1998  Ken Pizzini <ken@halcyon.com>
+
+       * dc/eval.c, doc/dc.texi, doc/dc.1: Changed the functionality
+         of the 'P' command, and added the 'n' command.  Due to
+         a quirk of the implementation of traditional dc, some
+         people have come to expect that the 'P' command on a
+         numeric argument in the range of 1 to 99 should output
+         the corresponding character, despite the fact that this
+         usage can have very weird results for numbers outside
+         that range.  This functionality is why the 'a' command
+         was introduced last March, but people really want it to
+         "just work" without needing to use the 'a' command.
+         Bowing to this demand, the 'P' command now does the
+         equivalent of "aP" if the argument is numeric, and the
+         'n' command has been added to support the previous
+         functionality of the 'P' command.
+
+       * dc/misc.c, dc/eval.c, dc/stack.c, dc/dc-proto.h:
+         Changed prototype for dc_print().  It now additionally
+         takes two flags, newline_p and discard_p, which it
+         passes through to dc_out_num() and dc_out_str() as
+         needed.
+
+       * h/version.h: dc is now up to version 1.1.4.
+
+Sat Sep 27 13:48:53 1997  Ken Pizzini <ken@halcyon.com>
+
+       * h/version.h: dc is now up to version 1.1.3.
+
+       * dc/stack.c, dc/array.c, dc/dc-proto.h, doc/dc.texi, doc/dc.1:
+         It has come to my attention that, though undocumented,
+         traditional dc stacked its arrays in parallel with the
+         stacking of simple registers.  I have now duplicated
+         this functionality.
+
+       * dc/dc.c, configure.in: line-buffer dc's output if setvbuf()
+         is supported.  This was requested to simplify using dc as
+         an inferior process under emacs.
+
+Fri Sep 26 19:56:15 1997  Ken Pizzini <ken@halcyon.com>
+
+       * dc/dc.c: fixed bug reporting address for --help.
+
+       * doc/dc.1, doc/dc.texi: corrected documentation of the maximum
+         admissible input base.
+
+       * doc/dc.texi: corrected sample code equivalence for the | command.
+
+       * lib/number.c: added a warning for non-zero scale in the base
+         for bc_raisemod().
+
+Fri Sep 26 18:15:31 1997  Ken Pizzini <ken@halcyon.com>
+
+       * dc/eval.c, doc/dc.1, doc/dc.texi: added !=, !<, and !> commands.
+
+       * dc/eval.c: eliminated double-free in 'a' command.
+
+       * dc/dc.c: changed placment of check for filename "-" so that
+        "-f -" will work.
+
+       * h/version.h: updated dc version to 1.1.2.
+
+Thu Sep 18 17:41:10 1997  Ken Pizzini <ken@halcyon.com>
+
+       * dc/eval.c: fixed off-by-one error for Q and q commands.
+
+       * dc/dc.c: added missing f: to third argument of getopt().
+
+       * h/version.h: updated dc version to 1.1.1.
+
+Thu May 22 08:24:08 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * lib/number.c(bc_sqrt): Fixed a bug that computed 0 for sqrt
+         of most numbers less than .000001.
+
+Thu May  1 10:41:38 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * Test/timetest: change path to bc executable.
+
+Wed Apr 30 12:00:00 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * Froze bc-1.04, started new directory for bc-1.05.
+         Fixes to bc-1.04 will be distributed as bc-1.05.
+
+Mon Apr 21 14:57:14 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/scan.l: Changed rules for single line comment to work
+         with lex as well as flex.  Also, do not include \n in the
+         comment.
+
+       * doc/bc.1: Clarified the single line comment and that \n
+         is processed outside of the comment.
+
+Sun Apr 20 22:21:30 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/scan.l: Added rules for a single line comment starting
+         with the # character.
+
+       * doc/bc.1: Documented the single line comment.
+
+       * bc/Makefile.am: Added DISTCLEANFILES for proper clean up.
+
+Sat Apr 19 22:08:05 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * dc/Makefile.am: Removed file from distribution list.
+
+       * h/version.h: Updated dc version to 1.1.
+
+Fri Apr 18 16:43:04 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * lib/number.c (bc_add, bc_sub) Added 1 to the length
+         of the memset call to make sure it zeroed all the
+         storage.
+
+Fri Apr 18 13:58:56 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * configure.in: Tweeks to get things right.  Not sure if things
+         changed much.  Still working with autoconf/automake to do
+         the right thing.
+
+Wed Apr 16 16:49:17 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/main.c (main): Changed processing of BC_ENV_ARGS.
+
+       * bc/main.c (parse_args): Removed "start" parameter.
+
+Tue Apr 15 13:21:28 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * acconfig.h: Included support for PACKAGE and VERSION.
+
+       * configure.in: More tweeks for automake support.
+
+       * h/number.h: Improve definition of MIN and MAX.
+
+       * doc/bc.1: Changed copyright, tweeked other text, added
+         e-mail address for bugs.
+
+       * doc/dc.1: Added copyright and GPL license information,
+         Changed a few .SH formats.
+
+Fri Apr 11 16:14:42 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * Makefile.am configure.in doc/Makefile.am lib/Makefile.am
+         bc/Makefile.am bc/bc.y dc/Makefile.am: Changes to accomodate
+         automake-1.1n (pre-release version of automake 1.2).
+
+       * bc/bc.y bc/sbc.y: Changes to make sure tokens are numbered the 
+         same in bc/bc.h and bc/sbc.h.
+
+       * bc/scan.l: Changes for automake's naming convention.
+
+       * NEWS: Fixed a typo.
+
+Thu Apr 10 14:42:55 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/{execute.c, global.c, libmath.b, load.c, main.c, sbc.y
+         scan.l, storage.c, util.c}:  Changed copyright comment and
+         added 1997 to copyright years.
+
+       * h/{bcdefs.h, const.h, global.h, number.h proto.h, version.h}:
+         Changed copyright comment and added 1997 to copyright years.
+
+       * h/version.h: Changed bc version to 1.04.
+
+       * lib/number.c: Changed copyright comment and added 1997 to 
+         copyright years.
+
+       * lib/vfprintf.c: Noted that this was only for minix.
+
+       * NEWS, README: README is now comp.sources.reviewed readme only.
+         NEWS now lists changes from version to version.
+
+Thu Apr 10 13:41:56 1997  Phil Nelson  <phil@fawn.cs.wwu.edu>
+
+       * Makefile.am: Removed FIXME stuff.
+
+Thu Apr 8 13:39:53 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/Makefile.am: Remove files that should not be distributed. 
+
+Mon Apr  7 17:14:28 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * Makefile.am: Removed Misc directory from distribution.
+
+Mon Apr  7 16:16:01 1997  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc/sbc.y: Corrected use of nextarg().
+
+Tue Mar 25 19:32:28 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * dc/eval.c, dc/misc.c, dc/stack.c, dc/string.c,
+         dc/dc.h, dc/dc-proto.h, dc/dc.c, dc/numeric.c,
+         doc/dc.texi: updated years in copyright
+         notices.
+
+       * dc/dc.1: updated last-revision date.
+
+Tue Mar 25 16:35:46 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * lib/number.c: give a run-time warning in bc_raisemod()
+         if the modulus does not appear to be an integer.
+
+       * doc/dc.texi, doc/dc.1: documented a warning against
+         the use of the new | command in conjunction with a
+         non-integral modulus.
+
+Tue Mar 25 15:36:04 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * dc/string.c: dc_out_str() updated to use fwrite()
+         instead of printf(), to allow for the existence of
+         a NUL character in the string.
+
+Tue Mar 25 13:42:51 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * doc/dc.texi, doc/dc.1: added documentation for new | command.
+
+Tue Mar 25 13:19:55 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * dc/dc-proto.h: added prototype for dc_triop().
+
+Tue Mar 25 12:00:38 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * lib/number.c: add bc_modexp() modular-exponentiation function.
+
+       * h/proto.h: add prototypes for bc_modexp() and bc_divmod().
+
+Tue Mar 25 09:07:13 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * doc/dc.texi, doc/dc.1: updated documentation with the
+         new command-line options.
+
+       * doc/dc.texi, doc/dc.1: updated documentation with the
+         new '~', 'r', and 'a' commands.
+
+       * dc/dc.c: added bug reporting information to --version text.
+
+Mon Mar 24 19:37:30 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * lib/number.c: added new "bc_divmod" function.
+
+       * dc/numeric.c: added new "dc_divrem" glue function to bc_divmod.
+
+       * dc/stack.c: added new "dc_binop2" function.
+
+       * dc/dc-proto.h: added new prototypes for dc_divrem() and dc_binop2().
+
+       * dc/eval.c, dc/numeric.c: add new '~' command which
+         returns both the quotient and remainder from division.
+
+Mon Mar 24 18:13:42 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * dc/eval.c: Add new 'r' (reverse top two stack elements) command.
+
+Mon Mar 24 17:47:02 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * dc/misc.c: split out the main() related functions into
+         a seperate dc/dc.c file.
+
+       * dc/Makefile.am: updated to reflect this split.
+
+Sat Mar  1 04:57:54 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * dc/misc.c: added "--file" option.
+
+Sat Mar  1 02:13:06 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * dc/eval.c: fixed bug of an excess increment in
+         dc_evalstr()'s DC_COMMENT case.  (Probably would
+         never show up in practice, but did violate the
+         letter of the C Standard.)
+
+       * renamed dc/number.c to dc/numeric.c, to avoid
+         confusion with lib/number.c.
+
+Thu Feb 27 19:45:45 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * dc/string.c, dc/dc.h: changed implementation of dc_str
+         type from a void * to a type which is only completed
+         in dc/string.c.  No functional change, just prettier code.
+
+Thu Feb 27 18:25:19 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * Cleaned up Makefile.am files.
+
+Thu Feb  6 00:41:02 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * Noticed pre-autoconf vestages (NO_XXX configuration options);
+         fixed to refer to autoconf HAVE_XXX definitions.
+
+       * The definition of BC_XXX values in h/const.h might
+         conflict with values of the same name from <limits.h>;
+         fixed to override without spewing warnings.
+
+       * Added check for ptrdiff_t to configure.in; removed
+         special ptrdiff_t definition from dc/string.c .
+
+Wed Feb  5 22:28:37 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * Only compile (guts of) lib/vfprintf.c if system does
+         not have its own version.
+
+Wed Feb  5 22:26:16 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * Changed dc/misc.c source to use standard GNU option
+         parsing routine (instead of special-case code).
+
+       * Added "-e" option to dc.
+
+       * Bumped dc version number to 1.0.4.
+
+Wed Feb  5 22:08:06 1997  Ken Pizzini  <ken@halcyon.com>
+
+       * rearranged source layout (added subdirectory structure);
+         removed "dc-" prefix from dc C source in its new home.
+
+       * merged bc's "version.h" and dc's "dc-version.h" files
+         into h/version.h; patched dc/misc.c to refer to new
+         DC_VERSION macro name.
+
+       * Tweaked configure.in in anticipation of using automake.
+
+Wed Jul 24 16:27:20 1996  Phil Nelson  <phil@cs.wwu.edu>
+
+       * number.c (out_num): Move free of t_num to proper place.
+
+Mon Jun  3 00:31:10 1996  Phil Nelson  <phil@cs.wwu.edu>
+
+       * number.c: (bc_sqrt, is_near_zero) Was hanging in an infinite
+         loop on sqrt(.9999).  Rewrote to take difference.  New routine
+         is_near_zero to check for one digit off.
+
+Thu Feb 22 12:14:38 1996  Phil Nelson  <phil@cs.wwu.edu>
+
+       * dc-eval.c (dc_func): Added the 'a' (number to ascii character)
+         command.
+
+Thu Feb 22 11:55:15 1996  Phil Nelson  <phil@cs.wwu.edu>
+
+       * dc-eval.c: (Changes from Ken) Changes dealing with stdin_lookahead
+         and peekc.
+
+       * dc-misc.c: (Changes from Ken) Changes in option processing.
+
+       * dc-version.c: (Change from Ken) Version is 1.0.2.
+
+Mon Oct  9 15:40:06 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * execute.c (execute): Add a pop to 'W' and 'P' codes.  Otherwise,
+         the stack continues to grow.
+
+       * number.c (out_num): Free all bc_nums used.
+
+Thu Jun 29 00:35:57 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc.1: Added information about long options and use of the
+         readline library.
+
+Wed Jun 28 21:03:45 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * scan.l: rl_input: detect EOF.
+
+Wed Jun 28 19:03:51 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * Makefile.in: fbc target, changed $(LEXLIB) => $(LIBS)
+
+Wed Jun 28 01:33:07 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * acconfig.h, bc.y, scan.l, storage.c, util.c, configure.in:
+         Improved readline support with a new pseudo variable "history" 
+         that controls the number of history lines available.
+         Also removed "optional" history.
+
+Wed Jun 28 01:03:52 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * getopt.h, getopt.c, getopt1.c: Imported from glibc-1.09
+         to allow long option processing.
+
+       * main.c (parse_args): Make it use long arguments.
+
+       * global.h: Change option flag variables from "char" to "int"
+         to allow long_arguments easy access to the variables.
+
+       * Makefile.in: Add getopt.h, getopt.c, and getopt1.c in the
+         proper places in the Makefile.
+
+Fri Jun 23 12:00:16 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * scan.l, main.c (main), acconfig.h, configure.in:
+         Added support for readline input on stdin.
+
+Thu Jun 22 20:08:57 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc.1: Change documentation on POSIX array parameter support.
+
+Fri Apr  7 12:29:28 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * main.c (parse_args): change "char ch" to "int optch" with
+         related changes.
+
+Thu Mar 23 04:11:00 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc.1: Update documentation to include new -q
+         option and the environment variables.
+
+Thu Mar 23 03:30:38 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bcdefs.h, global.h, main.c, util.c, bc.y: Reworked
+         argument processing to allow for getting arguments
+         from the environment and the command line.  Added
+         a new mechanism to access file names for opening
+         and for error messages.  Also added a "quiet"
+         option to turn off the welcome banner.
+
+Thu Mar 23 03:12:11 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * util.c: Corrected a comment.
+
+Tue Mar 21 13:36:24 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc.y: Added "opt_newline" to allow more newlines
+         in non-POSIX mode.
+
+Tue Mar 21 09:38:28 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * execute.c, main.c, util.c: Add support for user
+         defined line length, "correct POSIX line length",
+         no breaking of strings in std_only mode.  This
+         included adding a new function "out_schar" to
+         util.c.  Also removed "if (interactive)" before
+         all fflushes.
+
+Tue Mar 21 09:12:16 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * global.h: Added new variable "line_size". Cleaned up
+         some definitions by adding comments.
+
+Mon Mar 20 23:33:01 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * proto.h: Define getopt only if no unistd.h file.
+
+Mon Mar 20 23:23:34 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * number.c, proto.h, execute.c, storage.c, dc-number.c:
+         Changes to bc_add and bc_sub parameters to allow for
+         different scale results than were possible.  This is
+         for correct implementation of modulo.  All calls were
+         updated.
+
+Mon Mar 20 19:26:06 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * sbc.y: Removed second parameter on calls to arg_str to match
+         real function.
+
+Tue Feb 28 14:30:18 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * Makefile.in: Change realclean to maintainer-clean.  Added warning. 
+
+Mon Feb 27 17:08:24 1995  Phil Nelson  <phil@cs.wwu.edu>
+
+       * number.c: Change output to conform with POSIX standard for zero
+         only when the -s flag is given.  Otherwise it does the tradational
+         thing.
+
+       * dc-misc.c: Add the "std_only" flag, always set to zero.  This is
+         needed due to the above change.
+
+Tue Nov 29 15:18:20 1994  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc.1: Remove the "then" keyword in the if statement documentation.
+
+Mon Nov 28 16:50:25 1994  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc.1: Fixed a font change error.
+
+       * Makefile.in: Added missing \ in two targets.
+
+Tue Nov 22 11:09:08 1994  Phil Nelson  <phil@cs.wwu.edu>
+
+       * bc.1: clarified ibase and math routines.
+
+Thu Nov  3 14:09:31 1994  Phil Nelson  (phil@cs.wwu.edu)
+
+       * Makefile.in: added targets uninstall, installdirs and modified
+         other targets to get makes in a directory other than srcdir to
+         work.
+
+       * configure.in: added shell commands to get configure to work
+         correctly in directories other than srcdir.
+
+Wed Nov  2 10:18:19 1994  Phil Nelson  (phil@cs.wwu.edu)
+
+       * bc.1 bc.y bcdefs.h const.h execute.c global.c global.h load.c
+         main.c number.c number.h proto.h sbc.y scan.l storage.c util.c:
+         updated copyright to 1994.
+
+       * version.h: updated version number and copyright date.
+
+       * Makefile.in, configure.in, Install: updated for use with 
+         autoconf-2.0 and install-sh.  Changed target install a bit.
+
+       * install-sh: Included this file from the autoconf-2.0
+         distribution to have configure run without errors.
+
+       * README: updated to version 1.03.
+
+Mon Oct 31 10:26:28 1994  Phil Nelson  (phil@cs.wwu.edu)
+       
+       * Added Ken Pizzini's dc implementation that uses bc numeric
+         routines.  The following files have been added:
+         dc-Concerns   dc-array.c   dc-eval.c   dc-misc.c    dc-number.c 
+         dc-proto.h    dc-regdef.h  dc-stack.c  dc-string.c  dc-version.h
+         dc.1          dc.h         dc.texinfo
+
+       * dc-array.c: Added a conditional include of stdlib.h to get
+         size_t defined on my SunOS 4.1.3 system.
+
+       * configure.in: Added support for dc.
+
+       * Makefile.in: Added support for dc.  Added rule to make
+         config.h.in.
+
+Sun Aug  7 15:09:19 1994  Phil Nelson  (phil@cs.wwu.edu)
+
+       * configure.in, Makefile.in, acconfig.h: Add support for autoconf.
+         Removed old Makefile.
+
+Wed Jul 20 22:46:32 1994  Phil Nelson  (phil@cs.wwu.edu)
+
+       * bc.y: change definition of next_label in function definition.
+         Previous value of 0 caused break to not work.  It is now 1.
+
+Fri Apr  8 14:16:37 1994  Phil Nelson  (phil@cs.wwu.edu)
+
+       * Makefile: Change the distribution to include libmath.h.dist
+         which is a copy of libmath.h that has the compiled libmath.b.
+
+Sun Feb 13 01:08:14 1994  Phil Nelson  (phil@cs.wwu.edu)
+
+       * execute.c: Change the string quote characters to be more like
+         C.  \a => alert (bell) \b => backspace and added \q => ".
+
+       * bc.1: Updated information on above changes.
+
+Wed Oct 27 23:34:40 1993  Phil Nelson  (phil@cs.wwu.edu)
+
+       * Makefile: Changed compress to gzip.  Changed the
+         comment and definition of the DOT_IS_LAST compile option.
+
+       * scan.l: Changed DOT_IS_LAST to NO_DOT_LAST and changed
+         the test so "." is the last variable is standard.
+
+Wed May 19 15:15:12 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+       * number.c: Fixed output of negative numbers in bases other than
+         base 10.
+
+Wed Apr 21 11:56:31 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+       * bc.1: Changed Steve Sommars e-mail address.
+
+Wed Apr 14 12:13:39 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+       * sbc.y: removed leading , on first line.
+
+Wed Mar 31 16:12:39 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+       * bc.1: Updated segment number for function bodies.
+
+Thu Mar 11 15:34:34 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+       * Makefile: added version.h to bc.o's dependency list.
+
+Mon Mar  1 14:00:46 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+       * util.c: (nextarg) changed parameter "val" to be an int.
+
+Tue Feb 16 10:06:45 1993  Phil Nelson  (phil at cs.wwu.edu)
+
+       * util.c: (call_str, arg_str) added a function call_str that
+         correctly produces the string of argmuent types for a function
+         call.  arg_str produced them in the reverse order.  This
+         eliminated the need for the "comma" argument to arg_str, which
+         was removed.
+
+       * bc.y: changed the calls to arg_str to have only one parameter
+         in the function definition rule and replaced the call to arg_str
+         with call_str in the function call rule.
+
+Tue Nov 24 17:38:40 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * Makefile: Added LEXLIB definitions for use with lex.
+
+Thu Oct 22 13:43:16 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * number.c (bc_raise): Rearranged and added code to speed up
+         the computation by not doing unneeded multiplications.
+
+Wed Sep 30 10:43:52 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * global.h: Fixed documentation.
+
+Tue Sep 29 15:27:50 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * storage.c (process_params): Changed processing of more arguments
+         than in a function definition to just a return.  
+
+       * Makefile: Made changes to make it more in conformance with the
+         GNU coding standards.
+
+Tue Jul  7 21:09:07 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (const.h, bc.y, util.c) Added code so that when the math
+         library is loaded, redefinition of any math library function
+         will not cause the other functions to quit working correctly.
+         Before this change, redefining a(x) would cause s(x) and c(x)
+         to quit working and redefining s(x) would cause c(x) to quit
+         working.
+
+Wed Jul  1 14:35:29 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (libmath.b) Changed the calculation of scale for computing
+         e(x) and l(x).  This provides a little more accuracy in the
+         last digit at the expense of a little speed.
+
+       * (Test/checklib.b) Changed tests to be parameterized and test
+         more values.
+
+Thu Jun 25 09:22:59 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (configure) changed the script from looking in the
+         include directory for a .h file to asking cc (gcc) to
+         find the .h file.  This will allow better detection
+         of include files available to the C compiler.
+
+Wed Jun 24 22:11:37 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (bc.y) Added a warning for the "last" variable.
+
+       * (scan.l) Added code to allow for a single dot (.) to be the
+         same as the variable "last".  This is not a "standard" feature,
+         but is provided for those who want it.
+
+       * (Install) Documented the new define for dot (.).
+
+       * (bc.1) Documented the use of dot (.) for "last".
+
+       * (Makefile) Added an easy method for adding extra defines for
+         use during the compile.  Set DOT_IS_LAST as a standard
+         extra define.
+
+       * (number.c) Changed the code for sqrt for better speed.
+
+Mon Jun 22 21:47:05 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * Changed the name of math.h to libmath.h to avoid conflict
+         with /usr/include/math.h.  Changed all references to math.h
+         to libmath.h in all files.
+
+       * (configure) Changed the test for long strings accepted by
+         cc to not include libmath.h and thus not need to distribute
+         a file that is generated by the system.
+
+       * (Makefile) Changed PREFIX, BINDIR, LIBDIR, and MANDIR to
+         lower case.
+
+Tue Mar  3 10:16:07 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (main.c) Added missing } at line 140.
+
+       * (version.h) Changed date of version 1.02 to March 3, 1992.
+
+Mon Feb  3 16:07:57 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (version.h) Updated version number and date.
+
+       * (bc.1) Added a new "VERSION" section.
+
+Wed Jan 29 14:13:55 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (execute.c) Removed the setjmp and longjmp calls that may have
+         caused some problems with interrupted programs.
+
+Thu Jan 16 17:08:16 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (Makefile) Changed install to install the manual.
+
+Wed Jan  8 13:23:42 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * Change all copyright notices to include 1992.
+       
+       * (load.c) Added termination to "load_code" to ignore code
+         after an error has been found.
+
+       * (scan.l) Changed the check for NUL characters in STRING tokens
+         (before the close quote) to work correctly.  Also added code to
+         report illegal characters in a more readable output format.
+
+       * (bc.1) Added the exclusion of NUL characters from strings in
+         the "differences" section and updated date of last change.
+
+       * (const.h) Changed BC_MAX_SEGS to 16.
+
+Mon Jan  6 14:20:02 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (number.c) Changed the out_num routine to use a correct field
+         size for bases greater than 16.  e.g.  For base 1000, each
+         "digit" is a three digit number.
+
+       * (Makefile) Added the "8" flag to get an 8 bit scanner.
+
+       * (scan.l) Changed "char *" to "unsigned char *" to match the
+         declaration of yytext for the 8 bit scanner.  Also added code
+         to detect the null character in strings and generate an error.
+
+Sat Jan  4 20:32:20 1992  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (const.h) Changed BC_BASE_MAX to INT_MAX to allow more bases!
+
+Mon Dec 30 21:47:28 1991  Phil Nelson  (phil at cs.wwu.edu)
+
+       * (main.c) Fixed the bug that loaded the math library before
+         every file.
+
+       * (bc.y) Removed some type declarations that duplicated token
+         definitions so it could be run through bison.
+
+       * (load.c) Added a check for maximum code size.
+
+       * (Makefile) Added a prefix for LIBDIR and BINDIR so it can be
+         changed easily.
+
+Mon Nov 25 13:11:17 1991  Phil Nelson  (phil at cs.wwu.edu)
+
+       * Changed version number in version.h to 1.01 with current date.
+
+       * Changed LIBFILE definition in Makefile.
+
+       * Added a recursive function example to bc.1.
+
+Sun Nov 24 21:24:01 1991  Phil Nelson  (phil at cs.wwu.edu)
+
+       * Changed the Makefile to make sure configure is run first.
+         Added the $(CC) the configure call.  Moved some defines
+         toward the front of the Makefile to make sure they are
+         read by installers.  Also added SUBDIRS variable and updated
+         the GNU distribution to include the subdirectories.  Included
+         math.h in the distribution for use by configure.  Included
+         ChangeLog in the distribution.
+
+       * Split the README into README and Install.  Changed Install
+         to have current information.  Documented the STRINGS_H define.
+         Updated the version number in README.
+
+       * Added a check for <strings.h> in configure.
+
+Fri Nov 22 15:06:32 1991  Phil Nelson  (phil at cs.wwu.edu)
+
+       * Changed configure to check for varargs.h first.  Also, added
+         checks to see if long strings (math.h) are accepted by the
+         C compiler.  Also added parameters to configure.
+
+       * Deleted #include <sys/types.h> from proto.h.  Also made only
+         ANSI C compilers include <stdlib.h>.
+
+       * Changed the Makefile to have the install bin directory be
+         /usr/local/bin and the install lib directory be /usr/local/lib.
+
+       * Changed some files in the Test directory to eliminate the
+         <op>= form that some older bcs don't like.
+
+       * Made some small corrections in bc.1.
+
+Tue Oct 29 10:06:32 1991  Phil Nelson  (phil at cs.wwu.edu)
+
+       * Called current version 1.00.
+
+       * Submitted GNU bc-1.00 to comp.sources.reviewed
+
diff --git a/Examples/ckbook.b b/Examples/ckbook.b
new file mode 100644 (file)
index 0000000..5815ea0
--- /dev/null
@@ -0,0 +1,16 @@
+scale=2
+print "\nCheck book program!\n"
+print "  Remember, deposits are negative transactions.\n"
+print "  Exit by a 0 transaction.\n\n"
+
+print "Initial balance? "; bal = read()
+bal /= 1
+print "\n"
+while (1) {
+  "current balance = "; bal
+  "transaction? "; trans = read()
+  if (trans == 0) break;
+  bal -= trans
+  bal /= 1
+}
+quit
diff --git a/Examples/pi.b b/Examples/pi.b
new file mode 100644 (file)
index 0000000..0d840cf
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+   This is a program to determine the distribution of digits in the
+   fraction part of PI.   It will look at the first scale digits.
+
+   The results are left in the global variable digits.
+   digits[0] is the number of 0's in PI.
+
+   This program requires the math library.
+*/
+
+define pi () {
+  auto ix, pi, save_scale, work;
+
+  save_scale = scale;
+  scale += 5;
+  print "\n\nCalculating PI to ",scale," digits.  Please wait . . .";
+  pi = 4*a(1);
+  scale -= 5;
+  work = pi;
+
+  print "\nCounting digits. . .";
+  for (ix = 0; ix < 10; ix++) digits[ix] = 0;
+
+  /* Extract the One's digit from pi. */
+  scale = 0;
+  one_digit = work / 1;
+
+  for (ix = save_scale; ix > 0; ix--) {
+
+    /* Remove the One's digit and multiply by 10. */
+    scale = ix;
+    work = (work - one_digit) / 1 * 10;
+
+    /* Extract the One's digit. */
+    scale = 0;
+    one_digit = work / 1;
+
+    digits[one_digit] += 1;
+  }
+
+  /* Restore the scale. */
+  scale = save_scale;
+
+  /* Report. */
+  print "\n\n"
+  print "PI to ", scale, " digits is:\n", pi/1, "\n\n"
+  print "The frequency of the digits are:\n"
+  for (ix = 0; ix < 10; ix++) {
+    print "    ", ix, " - ", digits[ix], " times\n"
+  }
+
+  print "\n\n"
+}
diff --git a/Examples/primes.b b/Examples/primes.b
new file mode 100644 (file)
index 0000000..2b52ca7
--- /dev/null
@@ -0,0 +1,32 @@
+
+/* An example that finds all primes between 2 and limit. */
+
+define primes (limit) {
+    auto num, p, root, i
+
+    prime[1] = 2;
+    prime[2] = 3;
+    num = 2;
+    if (limit >= 2) print "prime 1 = 2\n"
+    if (limit >= 3) print "prime 2 = 3\n";
+    scale = 0;
+
+    for ( p=5; p <= limit; p += 2)  {
+       root = sqrt(p);
+       isprime = 1;
+       for ( i = 1;  i < num && prime[i] <= root; i++ ) {
+           if ( p % prime[i] == 0 ) {
+               isprime = 0;
+               break;
+            }
+       }
+       if (isprime) {
+           num += 1;
+           prime [num] = p;
+           print "prime ", num, " = ", p, "\n"
+       }
+     }
+}
+
+
+print "\ntyping 'primes (10)' will print all primes less than 10.\n"
diff --git a/Examples/twins.b b/Examples/twins.b
new file mode 100644 (file)
index 0000000..de910a7
--- /dev/null
@@ -0,0 +1,40 @@
+
+/* An example that finds all primes between 2 and limit. */
+
+define primes (limit) {
+    auto num, p, root, i
+
+    prime[1] = 2;
+    prime[2] = 3;
+    num = 2;
+    scale = 0;
+
+    for ( p=5; p <= limit; p += 2)  {
+       root = sqrt(p);
+       isprime = 1;
+       for ( i = 1;  i < num && prime[i] <= root; i++ ) {
+           if ( p % prime[i] == 0 ) {
+               isprime = 0;
+               break;
+            }
+       }
+       if (isprime) {
+           num += 1;
+           prime [num] = p;
+       }
+     }
+}
+
+
+print "\ntyping 'twins (10)' will print all twin primes less than 10.\n"
+
+define twins (limit) {
+   auto i;
+
+   i = primes(limit+2);
+
+   for (i=1; prime[i] > 0; i++) {
+      if ((prime[i]+2) == prime[i+1]) \
+       print "twins are ", prime[i], " and ", prime[i+1], "\n"
+   }
+}
diff --git a/FAQ b/FAQ
new file mode 100644 (file)
index 0000000..8043e26
--- /dev/null
+++ b/FAQ
@@ -0,0 +1,27 @@
+Because of frequent questions ....... here is the BC FAQ
+
+
+1) Why does BC have its own arbitrary precision number routines 
+   (found in lib/number.c) rather than using GMP?
+
+GMP has "integers" (no digits after a decimal), "rational numbers"
+(stored as 2 integers) and "floats".  None of these will correctly
+represent a POSIX BC number.  Floats are the closest, but will not
+behave correctly for many computations.  For example, BC numbers have
+a "scale" that represent the number of digits to represent after the
+decimal point.  The multiplying two of these numbers requires one to
+calculate an exact number of digits after the decimal point regardless
+of the number of digits in the integer part.  GMP floats have a
+"fixed, but arbitrary" mantissa and so multiplying two floats will end
+up dropping digits BC must calculate.
+
+2) The code "ibase=16; obase=10; FF" outputs FF, not 255.  Isn't this
+   a bug?
+
+No.  ibase changed the input base at that point.  The 10 is then in
+base 16 and thus is the value 16.  Therefore, both ibase and obase
+are 16 (decimal).  And FF (base 16) on input is printed as FF (base 16)
+on output.  So how can one get 255?  First, single digit numbers are
+not converted using ibase.  So A is always 10 (decimal).  The following
+code will always work.  "ibase=F+1; obase=A; FF" and that always prints
+255.
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..3b50ea9
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,176 @@
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes a while.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..84c2d74
--- /dev/null
@@ -0,0 +1,18 @@
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS = lib bc dc doc
+
+MAINTAINERCLEANFILES =  aclocal.m4 config.h.in configure Makefile.in \
+                       stamp-h $(distdir).tar.gz h/number.h depcomp missing
+
+dist-hook:
+       mkdir $(distdir)/h $(distdir)/Examples $(distdir)/Test
+       cp -p $(srcdir)/h/*.h $(distdir)/h
+       cp -p $(srcdir)/Examples/*.b $(distdir)/Examples
+       cp -p $(srcdir)/Test/*.b $(srcdir)/Test/*.bc $(distdir)/Test
+       cp -p $(srcdir)/Test/signum $(srcdir)/Test/timetest $(distdir)/Test
+       cp -p $(srcdir)/lib/testmul.c $(distdir)/lib
+       cp -p $(srcdir)/FAQ $(distdir)
+
+timetest:
+       (cd lib; $(MAKE) specialnumber)
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..84ed222
--- /dev/null
@@ -0,0 +1,599 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+       $(top_srcdir)/configure AUTHORS COPYING COPYING.LIB ChangeLog \
+       INSTALL NEWS depcomp install-sh missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+       html-recursive info-recursive install-data-recursive \
+       install-exec-recursive install-info-recursive \
+       install-recursive installcheck-recursive installdirs-recursive \
+       pdf-recursive ps-recursive uninstall-info-recursive \
+       uninstall-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d $(distdir) \
+    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BC_VERSION = @BC_VERSION@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DC_VERSION = @DC_VERSION@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+READLINELIB = @READLINELIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+SUBDIRS = lib bc dc doc
+MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \
+                       stamp-h $(distdir).tar.gz h/number.h depcomp missing
+
+all: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh:
+       @:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
+             cd $(srcdir) && $(AUTOMAKE) --gnu  \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           echo ' $(SHELL) ./config.status'; \
+           $(SHELL) ./config.status;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.h: stamp-h1
+       @if test ! -f $@; then \
+         rm -f stamp-h1; \
+         $(MAKE) stamp-h1; \
+       else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+       @rm -f stamp-h1
+       cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in:  $(am__configure_deps) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+       rm -f stamp-h1
+       touch $@
+
+distclean-hdr:
+       -rm -f config.h stamp-h1
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+       @failcom='exit 1'; \
+       for f in x $$MAKEFLAGS; do \
+         case $$f in \
+           *=* | --[!k]*);; \
+           *k*) failcom='fail=yes';; \
+         esac; \
+       done; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+         || eval $$failcom; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @failcom='exit 1'; \
+       for f in x $$MAKEFLAGS; do \
+         case $$f in \
+           *=* | --[!k]*);; \
+           *k*) failcom='fail=yes';; \
+         esac; \
+       done; \
+       dot_seen=no; \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+         *) list='$(SUBDIRS)' ;; \
+       esac; \
+       rev=''; for subdir in $$list; do \
+         if test "$$subdir" = "."; then :; else \
+           rev="$$subdir $$rev"; \
+         fi; \
+       done; \
+       rev="$$rev ."; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+         || eval $$failcom; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+ctags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+       done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+         include_option=--etags-include; \
+         empty_fix=.; \
+       else \
+         include_option=--include; \
+         empty_fix=; \
+       fi; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test ! -f $$subdir/TAGS || \
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+         fi; \
+       done; \
+       list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+         test -n "$$unique" || unique=$$empty_fix; \
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+           $$tags $$unique; \
+       fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+       $(am__remove_distdir)
+       mkdir $(distdir)
+       $(mkdir_p) $(distdir)/doc
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+       list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -d "$(distdir)/$$subdir" \
+           || $(mkdir_p) "$(distdir)/$$subdir" \
+           || exit 1; \
+           distdir=`$(am__cd) $(distdir) && pwd`; \
+           top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+           (cd $$subdir && \
+             $(MAKE) $(AM_MAKEFLAGS) \
+               top_distdir="$$top_distdir" \
+               distdir="$$distdir/$$subdir" \
+               distdir) \
+             || exit 1; \
+         fi; \
+       done
+       $(MAKE) $(AM_MAKEFLAGS) \
+         top_distdir="$(top_distdir)" distdir="$(distdir)" \
+         dist-hook
+       -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+         ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+         ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+         ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+       || chmod -R a+r $(distdir)
+dist-gzip: distdir
+       tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(am__remove_distdir)
+dist-bzip2: distdir
+       tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+       $(am__remove_distdir)
+
+dist-tarZ: distdir
+       tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+       $(am__remove_distdir)
+
+dist-shar: distdir
+       shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+       $(am__remove_distdir)
+
+dist-zip: distdir
+       -rm -f $(distdir).zip
+       zip -rq $(distdir).zip $(distdir)
+       $(am__remove_distdir)
+
+dist dist-all: distdir
+       tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+       $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       case '$(DIST_ARCHIVES)' in \
+       *.tar.gz*) \
+         GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+       *.tar.bz2*) \
+         bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+       *.tar.Z*) \
+         uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+       *.shar.gz*) \
+         GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+       *.zip*) \
+         unzip $(distdir).zip ;;\
+       esac
+       chmod -R a-w $(distdir); chmod a+w $(distdir)
+       mkdir $(distdir)/_build
+       mkdir $(distdir)/_inst
+       chmod a-w $(distdir)
+       dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+         && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+         && cd $(distdir)/_build \
+         && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+           $(DISTCHECK_CONFIGURE_FLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+         && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+               distuninstallcheck \
+         && chmod -R a-w "$$dc_install_base" \
+         && ({ \
+              (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+                   distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+             } || { rm -rf "$$dc_destdir"; exit 1; }) \
+         && rm -rf "$$dc_destdir" \
+         && $(MAKE) $(AM_MAKEFLAGS) dist \
+         && rm -rf $(DIST_ARCHIVES) \
+         && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+       $(am__remove_distdir)
+       @(echo "$(distdir) archives ready for distribution: "; \
+         list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+         sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+       @cd $(distuninstallcheck_dir) \
+       && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+          || { echo "ERROR: files left after uninstall:" ; \
+               if test -n "$(DESTDIR)"; then \
+                 echo "  (check DESTDIR support)"; \
+               fi ; \
+               $(distuninstallcheck_listfiles) ; \
+               exit 1; } >&2
+distcleancheck: distclean
+       @if test '$(srcdir)' = . ; then \
+         echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+         exit 1 ; \
+       fi
+       @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+         || { echo "ERROR: files left in build directory after distclean:" ; \
+              $(distcleancheck_listfiles) ; \
+              exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile config.h
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf $(top_srcdir)/autom4te.cache
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+       check-am clean clean-generic clean-recursive ctags \
+       ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-hook \
+       dist-shar dist-tarZ dist-zip distcheck distclean \
+       distclean-generic distclean-hdr distclean-recursive \
+       distclean-tags distcleancheck distdir distuninstallcheck dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-exec install-exec-am \
+       install-info install-info-am install-man install-strip \
+       installcheck installcheck-am installdirs installdirs-am \
+       maintainer-clean maintainer-clean-generic \
+       maintainer-clean-recursive mostlyclean mostlyclean-generic \
+       mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
+       uninstall uninstall-am uninstall-info-am
+
+
+dist-hook:
+       mkdir $(distdir)/h $(distdir)/Examples $(distdir)/Test
+       cp -p $(srcdir)/h/*.h $(distdir)/h
+       cp -p $(srcdir)/Examples/*.b $(distdir)/Examples
+       cp -p $(srcdir)/Test/*.b $(srcdir)/Test/*.bc $(distdir)/Test
+       cp -p $(srcdir)/Test/signum $(srcdir)/Test/timetest $(distdir)/Test
+       cp -p $(srcdir)/lib/testmul.c $(distdir)/lib
+       cp -p $(srcdir)/FAQ $(distdir)
+
+timetest:
+       (cd lib; $(MAKE) specialnumber)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..b1b8616
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,87 @@
+This is GNU bc version 1.07.  (And dc version 1.4)
+
+Changes in bc from 1.06 to 1.07.
+    Added void functions.
+    Bug fixes:
+       fixes bug in load_code introduced by mathlib string storage in 1.06.
+       fix to get long options working.
+       signal code clean-up.
+       fixed a bug in the AVL tree routines.
+       fixed math library to work properly when called with ibase not 10.
+       fixed a symbol table bug when using more than 32 names.
+       removed a double free.
+
+Changes in dc from 1.3 to 1.4:
+    Recognize and handle tail recursion.
+    Finally fix dc to trap interrupts, like the documentation has said it
+    should: aborts any executing macros, but does not exit the program.
+    Small bug fixes.
+    Minor code clean-up.
+    Changed to detect directories and generate errors.
+
+Changes in dc from 1.2 to 1.3:
+    Minor bug fixes.
+    New multiply algorithm of bc.
+
+Changes in bc from 1.05 to 1.06:
+    New multiply algoirthm and many other changes in lib/number.c
+    Function size now done dynamically.
+    Function syntax in non-posix mode allows newlines in more places.
+    Bug fixes:
+       improved computation of j(n,x).
+       enables readline only if interactive.
+       for statment bug fixed.
+       use int instead of char for readline char counts.
+       improved cosine accuracy.
+
+Changes in dc from 1.1 to 1.2:
+    added !< != !> commands
+    arrays now stack
+    output is now line buffered, provided setvbuf() is available
+    fixed known bugs in 'q', 'Q', 'a' commands, '-f' command-line option,
+      and documentation
+       changed the 'P' command's behavior on a numeric argument:
+         due to popular demand it now does the equivalent of 'aP'
+         (for small values)
+       added new 'n' command to do what the old 'P' command did
+
+Changes in bc from 1.04 to 1.05:
+    Solaris makes work better.
+    bug fixes
+       stdout now always does line buffering.
+       sqrt bug fixed for small numbers.
+       readline (if support is compiled in) is enabled only for
+               interactive executions of bc.
+
+
+This is GNU bc version 1.04.  (And dc version 1.1)
+
+Changes from 1.03
+
+       reorganization of source tree
+       use of automake
+
+       new commands for dc (|, ~, r, a)
+       new command line options for dc
+
+       fixed infinite loop in sqrt in bc
+       fixed an I/O bug in bc
+       made bc conform to POSIX for array parameters
+       added long option support for bc
+       new commandline options for bc (-q)
+       added support for readline to bc (use configure --with-readline)
+       command line argumens can now be taken from an environment variable
+       
+
+Changes from 1.02
+
+       minor bug fixes in bc.
+
+       addition of Ken Pizzini's dc program that uses the GNU bc 
+       arbitrary precision arithmetic routines.
+
+Changes from 1.01
+       
+       minor bug fixes.
+
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..2813fb8
--- /dev/null
+++ b/README
@@ -0,0 +1,86 @@
+GNU bc version 1.06:
+
+Extra configuration options:
+
+       --with-readline tells bc to use the readline package that allows
+         for editing input lines when run interactive.
+
+       --with-editline tells bc to use the BSD editline package that
+         allows for editing input lines when run interactive.
+
+Extra make steps:
+
+       The simple make compiles a version of bc with fixed parameters
+       for the recursive multiplication algorithm.  The fixed parameter
+       is the number of digits where a sequential algorithm is used
+       instead of the recursive algorithm.  It is set to a value that
+       is known good on a couple of machines. (Sparc Ultra 10, Pentium
+       II, 450.)  I'm calling this point the crossover point.
+
+       To make a version of bc with a custom crossover point for your
+       machine, do the following steps:
+
+               make timetest
+               make
+
+       The timetest step takes a minimum of 10 minutes to complete.
+
+
+-------- Original comp.sources.reviewed README --------
+
+Program: GNU bc
+Author: Philip A. Nelson
+E-mail: phil@cs.wwu.edu
+OS: UNIX (BSD, System V, MINIX, POSIX)
+Copying: GNU GPL version 2
+Copyright holder: Free Software Foundation, Inc. 
+Version: bc version 1.01
+Required: vsprintf and vfprintf routines.
+Machines: It has been compiled and run on the following environments:
+       BSD4.3 (VAX 11)
+       MINIX 1.5 (IBM PC, both K&R and ANSI compilers)
+       MINIX 1.5 (pc532)
+       SUN-OS 4.1 (SUN 3 and SUN 4)
+       SVR3V5 (Motorola 68K)
+       SVR3.2 (3B2)
+       SVR4.0.2 (a 386 box)
+       ULTRIX 4.1 (DEC 5000)
+       UTS (Amdahl)
+
+bc is an arbitrary precision numeric processing language.  Syntax is
+similar to C, but differs in many substantial areas.  It supports
+interactive execution of statements.  bc is a utility included in the
+POSIX P1003.2/D11 draft standard.
+
+This version was written to be a POSIX compliant bc processor with
+several extensions to the draft standard.  Option flags are available
+to cause warning or rejection of the extensions to the POSIX standard.
+For those who want only POSIX bc with no extensions, a grammar is
+provided for exactly the language described in the POSIX document.
+The grammar (sbc.y) comes from the POSIX document.  The Makefile
+contains rules to make sbc.  (for Standard BC)
+
+Since the POSIX document does not specify how bc must be implemented,
+this version does not use the historical method of having bc be a
+compiler for the dc calculator.  This version has a single executable
+that both compiles the language and runs the a resulting "byte code".
+The "byte code" is NOT the dc language.
+
+Also, included in the initial distribution is the library file
+vfprintf.c for MINIX systems.  My minix 1.5 did not have this file.
+Also, you should verify that vsprintf.c works correctly on your
+system.
+
+The extensions add some features I think are missing.  The major
+changes and additions for bc are (a) names are allowed to be full
+identifiers ([a-z][a-z0-9_]*), (b) addition of the &&, ||, and !
+operators, (c) allowing comparison and boolean operations in any
+expression, (d) addition of an else clause to the if statement, (e)
+addition of a new standard function "read()" that reads a number from
+the standard input under program control, (f) passing of arrays as
+parameters by variable, (g) addition of the "halt" statement that is
+an executable statement unlike the quit (i.e.  "if (1 == 0) quit" will
+halt bc but "if (1 == 0) halt" will not halt bc.), and (h) the
+addition of the special variable "last" that is assigned the value of
+each print as the number is printed.
+-----------------------------------------------------------------------
diff --git a/Test/BUG.bc b/Test/BUG.bc
new file mode 100644 (file)
index 0000000..254eefe
--- /dev/null
@@ -0,0 +1,40 @@
+/* <--- bug.bc ---><--- bug.bc ---><--- bug.bc ---><--- bug.bc ---> */
+
+/*
+ *  See the file "signum" for a description and reference for this
+ *  program.  
+ *
+ *  THIS BUG IS *NOT* IN GNU BC!!!
+ *
+ */
+
+obase=16
+ibase=16
+x=1A8F5C99605AE52      /* dividend                     */
+y=BB0B404              /* divisor                      */
+q=245A07AD             /* (correct) quotient           */
+r=147EB9E              /* (correct) remainder          */
+"Base 16
+"
+"x    = "; x           /* output numbers just to be sure... */
+"y    = "; y
+"quo  = "; q
+"rem  = "; r
+"x/y  = "; x/y         /* watch this result! */
+"x%y  = "; x%y         /* watch this result! */
+"y*q+r= "; y*q+r       /* check quotient & remainder   */
+/*
+ * Do the same thing in base 10:
+ */
+"
+Base 10
+"
+ibase=A
+obase=10
+"x    = "; x           /* output numbers just to be sure... */
+"y    = "; y
+"q    = "; q
+"r    = "; r
+"x/y  = "; x/y         /* watch this result! */
+"x%y  = "; x%y         /* watch this result! */
+"y*q+r= "; y*q+r       /* check quotient & remainder   */
diff --git a/Test/array.b b/Test/array.b
new file mode 100644 (file)
index 0000000..a0341ec
--- /dev/null
@@ -0,0 +1,14 @@
+"This tests arrays!
+"
+define p(x,y) {
+  auto i;
+  for (i=x; i<y; i++) a[i];
+}
+
+for (i=0; i<10; i++) a[i] = i;
+j = p(0,10);
+
+for (i=1000; i<1030; i++) a[i] = i;
+j = p(1000,1030);
+j = p(0,10);
+
diff --git a/Test/arrayp.b b/Test/arrayp.b
new file mode 100644 (file)
index 0000000..3f3ca50
--- /dev/null
@@ -0,0 +1,30 @@
+"This tests arrays!
+"
+define p(a[],x,y) {
+  auto i;
+  for (i=x; i<y; i++) a[i];
+}
+
+define m(a[],x,y) {
+  auto i;
+  for (i=x; i<y; i++) a[i] = i;
+}
+
+define m1(*a[],x,y) {
+  auto i;
+  print "m1\n"
+  for (i=x; i<y; i++) a[i] = i;
+}
+
+for (i=0; i<10; i++) a[i] = i;
+j = p(a[],0,10);
+
+j = m(b[],0,10);
+j = p(b[],0,10);
+
+print "---\n";
+j = m1(b[],0,10);
+j = p(b[],0,10);
+
+quit
+
diff --git a/Test/aryprm.b b/Test/aryprm.b
new file mode 100644 (file)
index 0000000..9d3f95b
--- /dev/null
@@ -0,0 +1,16 @@
+define p ( x[] ) {
+  auto i;
+  for (i=0; i<10; i++) x[i];
+}
+
+define m ( x[] ) {
+  auto i;
+  for (i=0; i<10; i++) x[i] *= 2;
+}
+    
+scale = 20;
+for (i=0; i<10; i++) a[i] = sqrt(i);
+
+p(a[]);
+m(a[]);
+p(a[]);
diff --git a/Test/atan.b b/Test/atan.b
new file mode 100644 (file)
index 0000000..e742279
--- /dev/null
@@ -0,0 +1,5 @@
+for (a=0; a<1000; a+=2) x=a(a)
+x
+for (a=0; a<2; a+=.01) x=a(a)
+x
+quit
diff --git a/Test/checklib.b b/Test/checklib.b
new file mode 100644 (file)
index 0000000..44c1fac
--- /dev/null
@@ -0,0 +1,109 @@
+define t (x,y,d,s,t) {
+   auto u, v, w, i, b, c;
+
+   if (s >= t) {
+     "Bad Scales. Try again.
+";   return;
+   }
+
+   for (i = x; i < y; i += d) {
+     scale = s;
+     u = f(i);
+     scale = t;
+     v = f(i);
+     scale = s;
+     w = v / 1;
+     b += 1;
+     if (u != w) {
+       c += 1;
+"
+Failed:  
+"
+       "  index = "; i;
+       "  val1 = "; u;
+       "  val2 = "; v;
+"
+"
+     }
+   }
+
+"
+Total tests:    "; b;
+"
+Total failures: "; c;
+"
+Percent failed: "; scale = 2; c*100/b;
+
+}
+
+/*
+   b = begining scale value, 
+   l = limit scale value,
+   i = increment scale value.
+
+   if b is set to a non-zero value before this file is executed,
+   b, l and i are not reset.
+*/
+
+if (b == 0) { b = 10; l = 61; i = 10; }
+
+"
+Checking e(x)"
+define f(x) {
+  return (e(x))
+}
+for (s=10; s<l; s=s+i) {
+"
+scale = "; s
+j = t(0,200,1,s,s+4)
+}
+
+"
+Checking l(x)"
+define f(x) {
+  return (l(x))
+}
+for (s=10; s<l; s=s+i) {
+"
+scale = "; s
+j = t(1,10000,25,s,s+4)
+}
+
+"
+Checking s(x)"
+define f(x) {
+  return (s(x))
+}
+for (s=10; s<l; s=s+i) {
+"
+scale = "; s
+j = t(0,8*a(1),.01,s,s+4)
+}
+
+"
+Checking a(x)"
+define f(x) {
+  return (a(x))
+}
+for (s=10; s<l; s=s+i) {
+"
+scale = "; s
+j = t(-1000,1000,10,s,s+4)
+}
+
+"
+Checking j(n,x)"
+define f(x) {
+  return (j(n,x))
+}
+for (s=10; s<l; s=s+i) {
+"
+n=0, scale = "; s
+n=0
+j = t(0,30,.1,s,s+4)
+"
+n=1, scale = "; s
+n=1
+j = t(0,30,.1,s,s+4)
+}
+
diff --git a/Test/div.b b/Test/div.b
new file mode 100644 (file)
index 0000000..3c7d377
--- /dev/null
@@ -0,0 +1,8 @@
+scale = 20
+a=2/3
+for (i=0; i<1000; i++) {
+  for (j=1; j<100; j++) b=a/j
+}
+b
+quit
+
diff --git a/Test/exp.b b/Test/exp.b
new file mode 100644 (file)
index 0000000..92c482c
--- /dev/null
@@ -0,0 +1,3 @@
+for (a=0; a<180; a+=.4) x=e(a)
+x
+quit
diff --git a/Test/fact.b b/Test/fact.b
new file mode 100644 (file)
index 0000000..1bf850a
--- /dev/null
@@ -0,0 +1,10 @@
+define f (x) {
+
+  if (x<=1) return(1)
+  return (f(x-1)*x)
+}
+
+for (a=1; a<600; a++) b=f(a)
+"length(b)= "; length(b)
+quit
+
diff --git a/Test/jn.b b/Test/jn.b
new file mode 100644 (file)
index 0000000..a4e0624
--- /dev/null
+++ b/Test/jn.b
@@ -0,0 +1,6 @@
+scale = 50
+for (a=0; a<=100; a += 20) {
+  for (b=0; b<=300; b += 20) x=j(a,b)
+  x
+}
+quit
diff --git a/Test/ln.b b/Test/ln.b
new file mode 100644 (file)
index 0000000..cd00232
--- /dev/null
+++ b/Test/ln.b
@@ -0,0 +1,4 @@
+scale = 60
+for (a=1; a<100000000000000000000000000000000000000; a = a*2) x=l(a)
+x
+quit
diff --git a/Test/mul.b b/Test/mul.b
new file mode 100644 (file)
index 0000000..722086f
--- /dev/null
@@ -0,0 +1,13 @@
+scale = 20
+for (i=0; i<10000; i++) {
+  for (j=1; j<100; j++) b=i*j
+}
+b
+for (i=0; i<10000; i++) {
+  for (j=1000000000000000000000000000000000000000000000000000000000000000000; \
+       j<1000000000000000000000000000000000000000000000000000000000000000100; \
+       j++) b=i*j
+}
+b
+quit
+
diff --git a/Test/raise.b b/Test/raise.b
new file mode 100644 (file)
index 0000000..a4314a0
--- /dev/null
@@ -0,0 +1,7 @@
+for (i=0; i<1000; i++) a = 2^i;
+length(a)
+for (i=3000; i<3100; i++) a = 3^i;
+length(a)
+for (i=200; i<220; i++) a = (4^100)^i;
+length(a)
+quit
diff --git a/Test/signum b/Test/signum
new file mode 100644 (file)
index 0000000..9e27d2d
--- /dev/null
@@ -0,0 +1,87 @@
+
+
+
+/* From gnu@cygnus.com Wed Jul 14 13:46:44 1993
+Return-Path: <gnu@cygnus.com>
+To: phil@cs.wwu.edu, gnu@cygnus.com
+Subject: bc/dc - no rest for the wicked
+Date: Tue, 06 Jul 93 19:12:40 -0700
+From: gnu@cygnus.com
+
+GNU bc 1.02 passes all these tests.  Can you add the test to the distribution?
+Putting it into a DejaGnu test case for GNU bc would be a great thing, too.
+(I haven't seen the Signum paper, maybe you can dig it out.)
+
+       John Gilmore
+       Cygnus Support
+
+------- Forwarded Message
+
+Date: Tue, 6 Jul 93 08:45:48 PDT
+From: uunet!Eng.Sun.COM!David.Hough@uunet.UU.NET (David Hough)
+Message-Id: <9307061545.AA14477@dgh.Eng.Sun.COM>
+To: numeric-interest@validgh.com
+Subject: bc/dc - no rest for the wicked
+
+Steve Sommars sent me a bc script which reproduces ALL the test cases from
+Dittmer's paper.    Neither SunOS 5.2 on SPARC nor 5.1 on x86 come out clean.
+Anybody else who has fixed all the bugs would be justified in 
+bragging about it here.  */
+
+
+/*Ingo Dittmer, ACM Signum, April 1993, page 8-11*/
+define g(x,y,z){
+       auto a
+       a=x%y
+       if(a!=z){
+"
+x=";x
+       "y=";y
+       "Should be ";z
+       "was       ";a
+       }
+}
+
+/*Table 1*/
+g=g(53894380494284,9980035577,2188378484)
+g=g(47907874973121,9980035577,3704203521)
+g=g(76850276401922,9980035577,4002459022)
+g=g(85830854846664,9980035577,2548884464)
+g=g(43915353970066,9980035577,3197431266)
+g=g(35930746212825,9980035577,2618135625)
+g=g(51900604524715,9980035577,4419524315)
+g=g(87827018005068,9980035577,2704927468)
+g=g(57887902441764,9980035577,3696095164)
+g=g(96810941031110,9980035577,4595934210)
+
+/*Table 2*/
+g=g(86833646827370,9980035577,7337307470)
+g=g(77850880592435,9980035577,6603091835)
+g=g(84836601050323,9980035577,6298645823)
+g=g(85835110016211,9980035577,6804054011)
+g=g(94817143459192,9980035577,6805477692)
+g=g(94818870293481,9980035577,8532311981)
+g=g(91823235571154,9980035577,6908262754)
+g=g(59885451951796,9980035577,5238489796)
+g=g(80844460893239,9980035577,6172719539)
+g=g(67869195894693,9980035577,4953971093)
+g=g(95813990985202,9980035577,5649446002)
+
+/*Skip Table 3, duplicate of line 1, table 1*/
+
+/*Table 4*/
+g=g(28420950579078013018256253301,17987947258,16619542243)
+g=g(12015118977201790601658257234,16687885701,8697335297)
+g=g(14349070374946789715188912007,13712994561,3605141129)
+g=g(61984050238512905451986475027,13337935089,5296182558)
+g=g(86189707791214681859449918641,17837971389,14435206830)
+g=g(66747908181102582528134773954,19462997965,8615839889)
+
+/*Table 6*/
+g=g(4999253,9998,253)
+g=g(8996373,9995,873)
+
+
+/* Added by Phil Nelson..... */
+"end of tests
+"
diff --git a/Test/sine.b b/Test/sine.b
new file mode 100644 (file)
index 0000000..18c4b57
--- /dev/null
@@ -0,0 +1,5 @@
+for (i=0; i<8*a(1); i=i+.01) x=s(i)
+x
+for (i=i; i<16*a(1); i=i+.01) x=s(i+.1234123412341234)
+x
+quit
diff --git a/Test/sqrt.b b/Test/sqrt.b
new file mode 100644 (file)
index 0000000..3fb548c
--- /dev/null
@@ -0,0 +1,13 @@
+scale = 5
+for (a=1; a<500; a++) r=sqrt(a)
+r
+scale = 10
+for (a=1; a<500; a++) r=sqrt(a)
+r
+scale = 25
+for (a=1; a<500; a++) r=sqrt(a)
+r
+scale = 40
+for (a=1; a<500; a++) r=sqrt(a)
+r
+quit
diff --git a/Test/sqrt1.b b/Test/sqrt1.b
new file mode 100644 (file)
index 0000000..c3ca269
--- /dev/null
@@ -0,0 +1,13 @@
+for (j=0; j<10; j++) {
+  a = .9;
+  b = .9+j;
+  scale = 2;
+  for (i=0; i<90; i++) {
+    scale += 1;
+    a /= 10;
+    b += a;
+    x = sqrt(b);
+  }
+  x;
+}
+quit
diff --git a/Test/sqrt2.b b/Test/sqrt2.b
new file mode 100644 (file)
index 0000000..bd0eaad
--- /dev/null
@@ -0,0 +1,10 @@
+scale = 20
+for (a=1; a<5000; a += 1) r=sqrt(a)
+r
+for (a=1; a<50000; a += 100) r=sqrt(a)
+r
+for (a=1; a<500000; a+=1000) r=sqrt(a)
+r
+for (a=1; a<5000000; a+=10000) r=sqrt(a)
+r
+quit
diff --git a/Test/testfn.b b/Test/testfn.b
new file mode 100644 (file)
index 0000000..7578fc5
--- /dev/null
@@ -0,0 +1,47 @@
+/* This function "t" tests the function "f" to see if computing at
+   two different scales has much effect on the accuracy. 
+   test from f(x) to f(y) incrementing the index by d.  f(i) is
+   computed at two scales, scale s and then scale t, where t>s.
+   the result from scale t is divided by 1 at scale s and the
+   results are compared.  If they are different, the function is
+   said to have failed.  It will then print out the value of i
+   (called index) and the two original values val1 (scale s) and
+   val2 (scale t) */
+
+define t (x,y,d,s,t) {
+   auto u, v, w, i, b, c;
+
+   if (s >= t) {
+     "Bad Scales. Try again.
+";   return;
+   }
+
+   for (i = x; i < y; i += d) {
+     scale = s;
+     u = f(i);
+     scale = t;
+     v = f(i);
+     scale = s;
+     w = v / 1;
+     b += 1;
+     if (u != w) {
+       c += 1;
+"
+Failed:  
+"
+       "  index = "; i;
+       "  val1 = "; u;
+       "  val2 = "; v;
+"
+"
+     }
+   }
+
+"
+Total tests:    "; b;
+"
+Total failures: "; c;
+"
+Percent failed: "; scale = 2; c*100/b;
+
+}
diff --git a/Test/timetest b/Test/timetest
new file mode 100755 (executable)
index 0000000..36d8d8e
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+#
+# Time the functions.
+#
+SYSBC=/usr/bin/bc
+if [ x$BC = x ] ; then
+  BC=../bc/bc
+fi
+for file in exp.b ln.b sine.b atan.b jn.b mul.b div.b raise.b sqrt.b fact.b
+do
+for prog in $SYSBC $BC $OTHERBC
+do
+echo Timing $file with $prog
+time $prog -l $file
+done
+done
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..20ce300
--- /dev/null
@@ -0,0 +1,883 @@
+# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005  Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Copyright (C) 2002, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+        [AM_AUTOMAKE_VERSION([1.9.6])])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 7
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 3
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`AS_DIRNAME("$mf")`
+  else
+    continue
+  fi
+  # Extract the definition of DEPDIR, am__include, and am__quote
+  # from the Makefile without running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  am__include=`sed -n 's/^am__include = //p' < "$mf"`
+  test -z "am__include" && continue
+  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  # Find all dependency output files, they are included files with
+  # $(DEPDIR) in their names.  We invoke sed twice because it is the
+  # simplest approach to changing $(DEPDIR) to its actual value in the
+  # expansion.
+  for file in `sed -n "
+    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`AS_DIRNAME(["$file"])`
+    AS_MKDIR_P([$dirpart/$fdir])
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 12
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+              [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+                            [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+                  [_AM_DEPENDENCIES(CC)],
+                  [define([AC_PROG_CC],
+                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+                  [_AM_DEPENDENCIES(CXX)],
+                  [define([AC_PROG_CXX],
+                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $1 | $1:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_PROG_LEX
+# -----------
+# Autoconf leaves LEX=: if lex or flex can't be found.  Change that to a
+# "missing" invocation, for better error output.
+AC_DEFUN([AM_PROG_LEX],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AM_MISSING_HAS_RUN])dnl
+AC_REQUIRE([AC_PROG_LEX])dnl
+if test "$LEX" = :; then
+  LEX=${am_missing_run}flex
+fi])
+
+# Check to see how 'make' treats includes.                 -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+       @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+#
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake.  There are at least two reasons why we must not
+# use `-m 0755':
+#   - it causes special bits like SGID to be ignored,
+#   - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are not thread-safe: if a
+# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out.  Consequently we
+# restrict ourselves to GNU make (using the --version option ensures
+# this.)
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # We used to keeping the `.' as first argument, in order to
+  # allow $(mkdir_p) to be used without argument.  As in
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.  However this is wrong
+  # for two reasons:
+  #  1. if the package is installed by a user who cannot write `.'
+  #     make install will fail,
+  #  2. the above comment should most certainly read
+  #     $(mkdir_p) $(DESTDIR)$(somedir)
+  #     so it does not work when $(somedir) is undefined and
+  #     $(DESTDIR) is not.
+  #  To support the latter case, we have to write
+  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+  #  so the `.' trick is pointless.
+  mkdir_p='mkdir -p --'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
diff --git a/bc/Makefile.am b/bc/Makefile.am
new file mode 100644 (file)
index 0000000..409e342
--- /dev/null
@@ -0,0 +1,48 @@
+## Process this file with automake to produce Makefile.in
+bin_PROGRAMS = bc
+
+bc_SOURCES = main.c bc.y scan.l execute.c load.c storage.c util.c global.c \
+            warranty.c
+
+EXTRA_DIST = bc.h bcdefs.h const.h fix-libmath_h global.h libmath.b proto.h \
+             sbc.y
+noinst_HEADERS = libmath.h
+
+DISTCLEANFILES = sbc sbc.c sbc.h
+
+MAINTAINERCLEANFILES = Makefile.in libmath.h bc.c bc.h scan.c \
+       bc.y bcdefs.h const.h execute.c fix-libmath_h \
+       global.c global.h libmath.b load.c main.c \
+       proto.h scan.l storage.c util.c
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../h
+LIBBC = ../lib/libbc.a
+LIBL = @LEXLIB@
+LDADD = $(LIBBC) $(LIBL) @READLINELIB@
+
+AM_YFLAGS = -d
+
+AM_CFLAGS = @CFLAGS@
+
+$(PROGRAMS): $(LIBBC)
+
+scan.o: bc.h
+global.o: libmath.h
+
+libmath.h: libmath.b
+       echo '{0}' > libmath.h
+       $(MAKE) fbc
+       ./fbc -c $(srcdir)/libmath.b </dev/null >libmath.h
+       $(srcdir)/fix-libmath_h
+       rm -f ./fbc ./global.o
+
+fbcOBJ = main.o bc.o scan.o execute.o global.o load.o storage.o util.o \
+         warranty.o
+fbc: $(fbcOBJ)
+       $(LINK) $(fbcOBJ) $(LIBBC) $(LIBL) $(READLINELIB) $(LIBS)
+
+sbcOBJ = main.o sbc.o scan.o execute.o global.o load.o storage.o util.o \
+         warranty.o
+sbc.o: sbc.c
+sbc: $(sbcOBJ)
+       $(LINK) $(sbcOBJ) $(LIBBC) $(LIBL) $(READLINELIB) $(LIBS)
diff --git a/bc/Makefile.in b/bc/Makefile.in
new file mode 100644 (file)
index 0000000..2f102e6
--- /dev/null
@@ -0,0 +1,492 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+bin_PROGRAMS = bc$(EXEEXT)
+subdir = bc
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in bc.c bc.h scan.c
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_bc_OBJECTS = main.$(OBJEXT) bc.$(OBJEXT) scan.$(OBJEXT) \
+       execute.$(OBJEXT) load.$(OBJEXT) storage.$(OBJEXT) \
+       util.$(OBJEXT) global.$(OBJEXT) warranty.$(OBJEXT)
+bc_OBJECTS = $(am_bc_OBJECTS)
+bc_LDADD = $(LDADD)
+am__DEPENDENCIES_1 = ../lib/libbc.a
+am__DEPENDENCIES_2 =
+bc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+SOURCES = $(bc_SOURCES)
+DIST_SOURCES = $(bc_SOURCES)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BC_VERSION = @BC_VERSION@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DC_VERSION = @DC_VERSION@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+READLINELIB = @READLINELIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+bc_SOURCES = main.c bc.y scan.l execute.c load.c storage.c util.c global.c \
+            warranty.c
+
+EXTRA_DIST = bc.h bcdefs.h const.h fix-libmath_h global.h libmath.b proto.h \
+             sbc.y
+
+noinst_HEADERS = libmath.h
+DISTCLEANFILES = sbc sbc.c sbc.h
+MAINTAINERCLEANFILES = Makefile.in libmath.h bc.c bc.h scan.c \
+       bc.y bcdefs.h const.h execute.c fix-libmath_h \
+       global.c global.h libmath.b load.c main.c \
+       proto.h scan.l storage.c util.c
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../h
+LIBBC = ../lib/libbc.a
+LIBL = @LEXLIB@
+LDADD = $(LIBBC) $(LIBL) @READLINELIB@
+AM_YFLAGS = -d
+AM_CFLAGS = @CFLAGS@
+fbcOBJ = main.o bc.o scan.o execute.o global.o load.o storage.o util.o \
+         warranty.o
+
+sbcOBJ = main.o sbc.o scan.o execute.o global.o load.o storage.o util.o \
+         warranty.o
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .l .o .obj .y
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  bc/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  bc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         if test -f $$p \
+         ; then \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+          echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+         else :; fi; \
+       done
+
+uninstall-binPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+         echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+         rm -f "$(DESTDIR)$(bindir)/$$f"; \
+       done
+
+clean-binPROGRAMS:
+       -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+bc.h: bc.c
+       @if test ! -f $@; then \
+         rm -f bc.c; \
+         $(MAKE) bc.c; \
+       else :; fi
+bc$(EXEEXT): $(bc_OBJECTS) $(bc_DEPENDENCIES) 
+       @rm -f bc$(EXEEXT)
+       $(LINK) $(bc_LDFLAGS) $(bc_OBJECTS) $(bc_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execute.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/global.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/load.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/storage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/warranty.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.l.c:
+       $(LEXCOMPILE) $<
+       sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@
+       rm -f $(LEX_OUTPUT_ROOT).c
+
+.y.c:
+       $(YACCCOMPILE) $<
+       if test -f y.tab.h; then \
+         to=`echo "$*_H" | sed \
+                -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
+                -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'`; \
+         sed -e "/^#/!b" -e "s/Y_TAB_H/$$to/g" -e "s|y\.tab\.h|$*.h|" \
+            y.tab.h >$*.ht; \
+         rm -f y.tab.h; \
+         if cmp -s $*.ht $*.h; then \
+           rm -f $*.ht ;\
+         else \
+           mv $*.ht $*.h; \
+         fi; \
+       fi
+       if test -f y.output; then \
+         mv y.output $*.output; \
+       fi
+       sed '/^#/ s|y\.tab\.c|$@|' y.tab.c >$@t && mv $@t $@
+       rm -f y.tab.c
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+         test -n "$$unique" || unique=$$empty_fix; \
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+           $$tags $$unique; \
+       fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+       for dir in "$(DESTDIR)$(bindir)"; do \
+         test -z "$$dir" || $(mkdir_p) "$$dir"; \
+       done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+       -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+       -rm -f bc.c
+       -rm -f bc.h
+       -rm -f scan.c
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+       clean-generic ctags distclean distclean-compile \
+       distclean-generic distclean-tags distdir dvi dvi-am html \
+       html-am info info-am install install-am install-binPROGRAMS \
+       install-data install-data-am install-exec install-exec-am \
+       install-info install-info-am install-man install-strip \
+       installcheck installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+       uninstall-am uninstall-binPROGRAMS uninstall-info-am
+
+
+$(PROGRAMS): $(LIBBC)
+
+scan.o: bc.h
+global.o: libmath.h
+
+libmath.h: libmath.b
+       echo '{0}' > libmath.h
+       $(MAKE) fbc
+       ./fbc -c $(srcdir)/libmath.b </dev/null >libmath.h
+       $(srcdir)/fix-libmath_h
+       rm -f ./fbc ./global.o
+fbc: $(fbcOBJ)
+       $(LINK) $(fbcOBJ) $(LIBBC) $(LIBL) $(READLINELIB) $(LIBS)
+sbc.o: sbc.c
+sbc: $(sbcOBJ)
+       $(LINK) $(sbcOBJ) $(LIBBC) $(LIBL) $(READLINELIB) $(LIBS)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/bc/bc.c b/bc/bc.c
new file mode 100644 (file)
index 0000000..56077a6
--- /dev/null
+++ b/bc/bc.c
@@ -0,0 +1,2620 @@
+/* A Bison parser, made by GNU Bison 2.1.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.1"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ENDOFLINE = 258,
+     AND = 259,
+     OR = 260,
+     NOT = 261,
+     STRING = 262,
+     NAME = 263,
+     NUMBER = 264,
+     ASSIGN_OP = 265,
+     REL_OP = 266,
+     INCR_DECR = 267,
+     Define = 268,
+     Break = 269,
+     Quit = 270,
+     Length = 271,
+     Return = 272,
+     For = 273,
+     If = 274,
+     While = 275,
+     Sqrt = 276,
+     Else = 277,
+     Scale = 278,
+     Ibase = 279,
+     Obase = 280,
+     Auto = 281,
+     Read = 282,
+     Random = 283,
+     Warranty = 284,
+     Halt = 285,
+     Last = 286,
+     Continue = 287,
+     Print = 288,
+     Limits = 289,
+     UNARY_MINUS = 290,
+     HistoryVar = 291,
+     Void = 292
+   };
+#endif
+/* Tokens.  */
+#define ENDOFLINE 258
+#define AND 259
+#define OR 260
+#define NOT 261
+#define STRING 262
+#define NAME 263
+#define NUMBER 264
+#define ASSIGN_OP 265
+#define REL_OP 266
+#define INCR_DECR 267
+#define Define 268
+#define Break 269
+#define Quit 270
+#define Length 271
+#define Return 272
+#define For 273
+#define If 274
+#define While 275
+#define Sqrt 276
+#define Else 277
+#define Scale 278
+#define Ibase 279
+#define Obase 280
+#define Auto 281
+#define Read 282
+#define Random 283
+#define Warranty 284
+#define Halt 285
+#define Last 286
+#define Continue 287
+#define Print 288
+#define Limits 289
+#define UNARY_MINUS 290
+#define HistoryVar 291
+#define Void 292
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 33 "bc.y"
+
+
+#include "bcdefs.h"
+#include "global.h"
+#include "proto.h"
+
+/* current function number. */
+int cur_func = -1;
+
+/* Expression encoded information -- See comment at expression rules. */
+#define EX_ASSGN 0 
+#define EX_REG   1
+#define EX_COMP  2
+#define EX_PAREN 4
+#define EX_VOID  8 
+#define EX_EMPTY 16
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 54 "bc.y"
+typedef union YYSTYPE {
+       char     *s_value;
+       char      c_value;
+       int       i_value;
+       arg_list *a_value;
+       } YYSTYPE;
+/* Line 196 of yacc.c.  */
+#line 185 "bc.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 219 of yacc.c.  */
+#line 197 "bc.c"
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if defined (__STDC__) || defined (__cplusplus)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     define YYINCLUDED_STDLIB_H
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+#  endif
+#  ifdef __cplusplus
+extern "C" {
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
+       && (defined (__STDC__) || defined (__cplusplus)))
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
+       && (defined (__STDC__) || defined (__cplusplus)))
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifdef __cplusplus
+}
+#  endif
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+        || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short int yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short int) + sizeof (YYSTYPE))                    \
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined (__GNUC__) && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)                                       \
+    do                                                                 \
+      {                                                                        \
+       YYSIZE_T yynewbytes;                                            \
+       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
+       Stack = &yyptr->Stack;                                          \
+       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+       yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                        \
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  2
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   719
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  53
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  36
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  112
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  198
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   292
+
+#define YYTRANSLATE(YYX)                                               \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,    42,    52,     2,
+      45,    46,    40,    38,    49,    39,     2,    41,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    44,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    50,     2,    51,    43,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    47,     2,    48,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned short int yyprhs[] =
+{
+       0,     0,     3,     4,     7,    10,    12,    15,    16,    18,
+      19,    21,    25,    28,    29,    31,    34,    38,    41,    45,
+      47,    50,    52,    54,    56,    58,    60,    62,    64,    66,
+      69,    70,    71,    72,    73,    88,    89,    98,    99,   100,
+     109,   113,   114,   118,   120,   124,   126,   128,   129,   130,
+     135,   136,   150,   151,   153,   154,   156,   157,   161,   165,
+     167,   171,   176,   181,   185,   191,   198,   205,   206,   208,
+     210,   214,   218,   224,   225,   227,   228,   230,   231,   236,
+     237,   242,   243,   248,   251,   255,   259,   263,   267,   271,
+     275,   279,   282,   284,   286,   290,   295,   298,   301,   306,
+     311,   316,   320,   324,   326,   331,   333,   335,   337,   339,
+     341,   342,   344
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      54,     0,    -1,    -1,    54,    55,    -1,    57,     3,    -1,
+      73,    -1,     1,     3,    -1,    -1,     3,    -1,    -1,    59,
+      -1,    57,    44,    59,    -1,    57,    44,    -1,    -1,    59,
+      -1,    58,     3,    -1,    58,     3,    59,    -1,    58,    44,
+      -1,    58,    44,    60,    -1,    60,    -1,     1,    60,    -1,
+      29,    -1,    34,    -1,    83,    -1,     7,    -1,    14,    -1,
+      32,    -1,    15,    -1,    30,    -1,    17,    82,    -1,    -1,
+      -1,    -1,    -1,    18,    61,    45,    81,    44,    62,    81,
+      44,    63,    81,    46,    64,    56,    60,    -1,    -1,    19,
+      45,    83,    46,    65,    56,    60,    71,    -1,    -1,    -1,
+      20,    66,    45,    83,    67,    46,    56,    60,    -1,    47,
+      58,    48,    -1,    -1,    33,    68,    69,    -1,    70,    -1,
+      70,    49,    69,    -1,     7,    -1,    83,    -1,    -1,    -1,
+      22,    72,    56,    60,    -1,    -1,    13,    75,     8,    45,
+      76,    46,    56,    47,    88,    77,    74,    58,    48,    -1,
+      -1,    37,    -1,    -1,    78,    -1,    -1,    26,    78,     3,
+      -1,    26,    78,    44,    -1,     8,    -1,     8,    50,    51,
+      -1,    40,     8,    50,    51,    -1,    52,     8,    50,    51,
+      -1,    78,    49,     8,    -1,    78,    49,     8,    50,    51,
+      -1,    78,    49,    40,     8,    50,    51,    -1,    78,    49,
+      52,     8,    50,    51,    -1,    -1,    80,    -1,    83,    -1,
+       8,    50,    51,    -1,    80,    49,    83,    -1,    80,    49,
+       8,    50,    51,    -1,    -1,    83,    -1,    -1,    83,    -1,
+      -1,    87,    10,    84,    83,    -1,    -1,    83,     4,    85,
+      83,    -1,    -1,    83,     5,    86,    83,    -1,     6,    83,
+      -1,    83,    11,    83,    -1,    83,    38,    83,    -1,    83,
+      39,    83,    -1,    83,    40,    83,    -1,    83,    41,    83,
+      -1,    83,    42,    83,    -1,    83,    43,    83,    -1,    39,
+      83,    -1,    87,    -1,     9,    -1,    45,    83,    46,    -1,
+       8,    45,    79,    46,    -1,    12,    87,    -1,    87,    12,
+      -1,    16,    45,    83,    46,    -1,    21,    45,    83,    46,
+      -1,    23,    45,    83,    46,    -1,    27,    45,    46,    -1,
+      28,    45,    46,    -1,     8,    -1,     8,    50,    83,    51,
+      -1,    24,    -1,    25,    -1,    23,    -1,    36,    -1,    31,
+      -1,    -1,     3,    -1,    88,     3,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned short int yyrline[] =
+{
+       0,   124,   124,   132,   134,   136,   138,   144,   145,   149,
+     150,   151,   152,   155,   156,   157,   158,   159,   160,   162,
+     163,   166,   168,   170,   179,   186,   196,   207,   209,   211,
+     214,   219,   231,   244,   213,   264,   263,   279,   285,   278,
+     299,   302,   301,   305,   306,   308,   314,   321,   323,   322,
+     334,   332,   359,   360,   367,   368,   371,   372,   374,   377,
+     379,   381,   385,   389,   391,   393,   397,   403,   404,   406,
+     414,   420,   428,   446,   450,   453,   459,   474,   473,   503,
+     502,   518,   517,   535,   543,   573,   580,   587,   594,   601,
+     608,   615,   622,   631,   647,   653,   672,   691,   714,   721,
+     728,   735,   741,   748,   750,   758,   760,   762,   764,   768,
+     775,   776,   777
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "ENDOFLINE", "AND", "OR", "NOT",
+  "STRING", "NAME", "NUMBER", "ASSIGN_OP", "REL_OP", "INCR_DECR", "Define",
+  "Break", "Quit", "Length", "Return", "For", "If", "While", "Sqrt",
+  "Else", "Scale", "Ibase", "Obase", "Auto", "Read", "Random", "Warranty",
+  "Halt", "Last", "Continue", "Print", "Limits", "UNARY_MINUS",
+  "HistoryVar", "Void", "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "';'",
+  "'('", "')'", "'{'", "'}'", "','", "'['", "']'", "'&'", "$accept",
+  "program", "input_item", "opt_newline", "semicolon_list",
+  "statement_list", "statement_or_error", "statement", "@1", "@2", "@3",
+  "@4", "@5", "@6", "@7", "@8", "print_list", "print_element", "opt_else",
+  "@9", "function", "@10", "opt_void", "opt_parameter_list",
+  "opt_auto_define_list", "define_list", "opt_argument_list",
+  "argument_list", "opt_expression", "return_expression", "expression",
+  "@11", "@12", "@13", "named_expression", "required_eol", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short int yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,    43,    45,
+      42,    47,    37,    94,    59,    40,    41,   123,   125,    44,
+      91,    93,    38
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    53,    54,    54,    55,    55,    55,    56,    56,    57,
+      57,    57,    57,    58,    58,    58,    58,    58,    58,    59,
+      59,    60,    60,    60,    60,    60,    60,    60,    60,    60,
+      61,    62,    63,    64,    60,    65,    60,    66,    67,    60,
+      60,    68,    60,    69,    69,    70,    70,    71,    72,    71,
+      74,    73,    75,    75,    76,    76,    77,    77,    77,    78,
+      78,    78,    78,    78,    78,    78,    78,    79,    79,    80,
+      80,    80,    80,    81,    81,    82,    82,    84,    83,    85,
+      83,    86,    83,    83,    83,    83,    83,    83,    83,    83,
+      83,    83,    83,    83,    83,    83,    83,    83,    83,    83,
+      83,    83,    83,    87,    87,    87,    87,    87,    87,    87,
+      88,    88,    88
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     0,     2,     2,     1,     2,     0,     1,     0,
+       1,     3,     2,     0,     1,     2,     3,     2,     3,     1,
+       2,     1,     1,     1,     1,     1,     1,     1,     1,     2,
+       0,     0,     0,     0,    14,     0,     8,     0,     0,     8,
+       3,     0,     3,     1,     3,     1,     1,     0,     0,     4,
+       0,    13,     0,     1,     0,     1,     0,     3,     3,     1,
+       3,     4,     4,     3,     5,     6,     6,     0,     1,     1,
+       3,     3,     5,     0,     1,     0,     1,     0,     4,     0,
+       4,     0,     4,     2,     3,     3,     3,     3,     3,     3,
+       3,     2,     1,     1,     3,     4,     2,     2,     4,     4,
+       4,     3,     3,     1,     4,     1,     1,     1,     1,     1,
+       0,     1,     2
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       2,     0,     1,     0,     0,    24,   103,    93,     0,    52,
+      25,    27,     0,    75,    30,     0,    37,     0,   107,   105,
+     106,     0,     0,    21,    28,   109,    26,    41,    22,   108,
+       0,     0,     0,     3,     0,    10,    19,     5,    23,    92,
+       6,    20,    83,    67,     0,   103,   107,    96,    53,     0,
+       0,    29,    76,     0,     0,     0,     0,     0,     0,     0,
+       0,    91,     0,     0,     0,    14,     4,     0,    79,    81,
+       0,     0,     0,     0,     0,     0,     0,    77,    97,   103,
+       0,    68,    69,     0,     0,     0,    73,     0,     0,     0,
+       0,   101,   102,    45,    42,    43,    46,    94,     0,    17,
+      40,    11,     0,     0,    84,    85,    86,    87,    88,    89,
+      90,     0,     0,    95,     0,   104,    54,    98,     0,    74,
+      35,    38,    99,   100,     0,    16,    18,    80,    82,    78,
+      70,   103,    71,    59,     0,     0,     0,    55,    31,     7,
+       0,    44,     0,     0,     0,     0,     7,     0,    73,     8,
+       0,     7,    72,    60,     0,     0,     0,    63,     0,     0,
+       0,    47,     0,    61,    62,   110,     0,     0,     0,    32,
+      48,    36,    39,   111,    56,    64,     0,     0,    73,     7,
+     112,     0,    50,    65,    66,     0,     0,     0,     0,    33,
+      49,    57,    58,     0,     7,    51,     0,    34
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+      -1,     1,    33,   150,    34,    64,    65,    36,    53,   148,
+     178,   194,   139,    55,   140,    60,    94,    95,   171,   179,
+      37,   188,    49,   136,   182,   137,    80,    81,   118,    51,
+      38,   111,   102,   103,    39,   174
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -144
+static const short int yypact[] =
+{
+    -144,   188,  -144,   392,   595,  -144,   -36,  -144,   484,   -31,
+    -144,  -144,   -32,   595,  -144,   -11,  -144,   -10,    -7,  -144,
+    -144,    -6,    -5,  -144,  -144,  -144,  -144,  -144,  -144,  -144,
+     595,   595,   222,  -144,     2,  -144,  -144,  -144,   676,    14,
+    -144,  -144,   131,   621,   595,   -27,  -144,  -144,  -144,    54,
+     595,  -144,   676,    20,   595,    21,   595,   595,    13,    37,
+     569,  -144,   425,   535,     1,  -144,  -144,   318,  -144,  -144,
+     595,   595,   595,   595,   595,   595,   595,  -144,  -144,   -23,
+      41,    36,   676,    39,    43,   436,   595,   445,   595,   485,
+     494,  -144,  -144,  -144,  -144,    40,   676,  -144,   270,   535,
+    -144,  -144,   595,   595,   -22,    51,    51,     4,     4,     4,
+       4,   595,   105,  -144,   647,  -144,    23,  -144,    53,   676,
+    -144,   676,  -144,  -144,   569,  -144,  -144,   131,   123,   -22,
+    -144,   -20,   676,    45,    91,    94,    57,    55,  -144,   102,
+      60,  -144,   352,    56,    58,    65,   102,    24,   595,  -144,
+     535,   102,  -144,  -144,    67,    68,    69,    70,   115,   116,
+      81,   109,   535,  -144,  -144,   132,    86,    88,    89,  -144,
+    -144,  -144,  -144,  -144,     7,  -144,    92,    97,   595,   102,
+    -144,    23,  -144,  -144,  -144,    99,   535,    12,   222,  -144,
+    -144,  -144,  -144,     9,   102,  -144,   535,  -144
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const short int yypgoto[] =
+{
+    -144,  -144,  -144,  -143,  -144,   -39,     0,    -3,  -144,  -144,
+    -144,  -144,  -144,  -144,  -144,  -144,    27,  -144,  -144,  -144,
+    -144,  -144,  -144,  -144,  -144,   -29,  -144,  -144,  -141,  -144,
+      -2,  -144,  -144,  -144,   145,  -144
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -16
+static const short int yytable[] =
+{
+      41,    35,    42,   156,    98,    66,    48,   160,   162,    43,
+     180,    52,    98,    50,    44,   191,    71,    72,    73,    74,
+      75,    76,    43,    44,    77,    43,    78,   112,    61,    62,
+     142,   133,   157,   181,    54,    56,   186,   185,    57,    58,
+      59,    82,    83,    68,    69,    99,    67,    76,    85,   100,
+      70,   196,    87,    99,    89,    90,   192,   195,    96,    91,
+      41,   147,    84,   134,   158,    86,    88,   101,   104,   105,
+     106,   107,   108,   109,   110,   135,   159,    71,    72,    73,
+      74,    75,    76,    92,   119,   114,   121,   113,   116,   124,
+     115,    73,    74,    75,    76,   143,   126,   138,   125,   144,
+     127,   128,   145,   146,   147,   149,   151,   153,   154,   129,
+      83,     4,   132,     6,     7,   155,   165,     8,   163,   164,
+     166,    12,    96,   167,   168,   169,    17,    68,    18,    19,
+      20,   170,    21,    22,    70,   173,    25,   175,   176,   177,
+      83,    29,    70,   183,    30,   189,   119,   161,   184,   193,
+      31,   141,   187,    47,     0,     0,   130,     0,     0,   172,
+       0,    71,    72,    73,    74,    75,    76,     0,     0,    71,
+      72,    73,    74,    75,    76,     0,   119,     0,     0,     0,
+       0,     0,     0,   190,     0,     0,     0,     0,     2,     3,
+       0,    -9,     0,   197,     4,     5,     6,     7,     0,     0,
+       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+       0,    18,    19,    20,     0,    21,    22,    23,    24,    25,
+      26,    27,    28,    63,    29,   -13,     0,    30,     4,     5,
+       6,     7,    -9,    31,     8,    32,    10,    11,    12,    13,
+      14,    15,    16,    17,     0,    18,    19,    20,     0,    21,
+      22,    23,    24,    25,    26,    27,    28,     0,    29,     0,
+       0,    30,     0,     0,     0,     0,   -13,    31,     0,    32,
+     -13,    63,     0,   -15,     0,     0,     4,     5,     6,     7,
+       0,     0,     8,     0,    10,    11,    12,    13,    14,    15,
+      16,    17,     0,    18,    19,    20,     0,    21,    22,    23,
+      24,    25,    26,    27,    28,     0,    29,     0,     0,    30,
+       0,     0,     0,     0,   -15,    31,     0,    32,   -15,    63,
+       0,   -12,     0,     0,     4,     5,     6,     7,     0,     0,
+       8,     0,    10,    11,    12,    13,    14,    15,    16,    17,
+       0,    18,    19,    20,     0,    21,    22,    23,    24,    25,
+      26,    27,    28,     0,    29,     0,     0,    30,     4,     0,
+       6,     7,   -12,    31,     8,    32,     0,     0,    12,     0,
+       0,     0,     0,    17,     0,    18,    19,    20,     0,    21,
+      22,     0,     0,    25,     0,     0,     0,     0,    29,     0,
+       0,    30,     0,     0,     0,    40,     0,    31,     4,     5,
+       6,     7,     0,   152,     8,     0,    10,    11,    12,    13,
+      14,    15,    16,    17,     0,    18,    19,    20,     0,    21,
+      22,    23,    24,    25,    26,    27,    28,     0,    29,    68,
+      69,    30,     0,     0,     0,     0,    70,    31,     0,    32,
+      68,    69,     0,     0,     0,     0,     0,    70,     0,    68,
+      69,     0,     0,     0,     0,     0,    70,     0,     0,     0,
+       0,     0,     0,    71,    72,    73,    74,    75,    76,     0,
+       0,    97,     0,     0,    71,    72,    73,    74,    75,    76,
+       0,     0,   117,    71,    72,    73,    74,    75,    76,    68,
+      69,   120,    45,     0,     0,     0,    70,     0,    68,    69,
+       0,     0,     0,     0,     0,    70,     0,    46,    19,    20,
+       0,     0,     0,     0,     0,    25,     0,     0,     0,     0,
+      29,     0,     0,    71,    72,    73,    74,    75,    76,     0,
+       0,   122,    71,    72,    73,    74,    75,    76,     0,     0,
+     123,     4,     5,     6,     7,     0,     0,     8,     0,    10,
+      11,    12,    13,    14,    15,    16,    17,     0,    18,    19,
+      20,     0,    21,    22,    23,    24,    25,    26,    27,    28,
+       0,    29,     0,     0,    30,     4,    93,     6,     7,     0,
+      31,     8,    32,     0,     0,    12,     0,     0,     0,     0,
+      17,     0,    18,    19,    20,     0,    21,    22,     0,     0,
+      25,     4,     0,     6,     7,    29,     0,     8,    30,     0,
+       0,    12,     0,     0,    31,     0,    17,     0,    18,    19,
+      20,     0,    21,    22,     0,     0,    25,     4,     0,    79,
+       7,    29,     0,     8,    30,     0,     0,    12,     0,     0,
+      31,     0,    17,     0,    18,    19,    20,     0,    21,    22,
+       0,     0,    25,     4,     0,   131,     7,    29,     0,     8,
+      30,     0,     0,    12,     0,     0,    31,     0,    17,     0,
+      18,    19,    20,     0,    21,    22,     0,     0,    25,     0,
+      68,    69,     0,    29,     0,     0,    30,    70,     0,     0,
+       0,     0,    31,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    71,    72,    73,    74,    75,    76
+};
+
+static const short int yycheck[] =
+{
+       3,     1,     4,   146,     3,     3,    37,   148,   151,    45,
+       3,    13,     3,    45,    50,     3,    38,    39,    40,    41,
+      42,    43,    45,    50,    10,    45,    12,    50,    30,    31,
+      50,     8,     8,    26,    45,    45,   179,   178,    45,    45,
+      45,    43,    44,     4,     5,    44,    44,    43,    50,    48,
+      11,   194,    54,    44,    56,    57,    44,    48,    60,    46,
+      63,    49,     8,    40,    40,    45,    45,    67,    70,    71,
+      72,    73,    74,    75,    76,    52,    52,    38,    39,    40,
+      41,    42,    43,    46,    86,    49,    88,    46,    45,    49,
+      51,    40,    41,    42,    43,    50,    99,    44,    98,     8,
+     102,   103,     8,    46,    49,     3,    46,    51,    50,   111,
+     112,     6,   114,     8,     9,    50,    47,    12,    51,    51,
+      50,    16,   124,     8,     8,    44,    21,     4,    23,    24,
+      25,    22,    27,    28,    11,     3,    31,    51,    50,    50,
+     142,    36,    11,    51,    39,    46,   148,   150,    51,   188,
+      45,   124,   181,     8,    -1,    -1,    51,    -1,    -1,   162,
+      -1,    38,    39,    40,    41,    42,    43,    -1,    -1,    38,
+      39,    40,    41,    42,    43,    -1,   178,    -1,    -1,    -1,
+      -1,    -1,    -1,   186,    -1,    -1,    -1,    -1,     0,     1,
+      -1,     3,    -1,   196,     6,     7,     8,     9,    -1,    -1,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      -1,    23,    24,    25,    -1,    27,    28,    29,    30,    31,
+      32,    33,    34,     1,    36,     3,    -1,    39,     6,     7,
+       8,     9,    44,    45,    12,    47,    14,    15,    16,    17,
+      18,    19,    20,    21,    -1,    23,    24,    25,    -1,    27,
+      28,    29,    30,    31,    32,    33,    34,    -1,    36,    -1,
+      -1,    39,    -1,    -1,    -1,    -1,    44,    45,    -1,    47,
+      48,     1,    -1,     3,    -1,    -1,     6,     7,     8,     9,
+      -1,    -1,    12,    -1,    14,    15,    16,    17,    18,    19,
+      20,    21,    -1,    23,    24,    25,    -1,    27,    28,    29,
+      30,    31,    32,    33,    34,    -1,    36,    -1,    -1,    39,
+      -1,    -1,    -1,    -1,    44,    45,    -1,    47,    48,     1,
+      -1,     3,    -1,    -1,     6,     7,     8,     9,    -1,    -1,
+      12,    -1,    14,    15,    16,    17,    18,    19,    20,    21,
+      -1,    23,    24,    25,    -1,    27,    28,    29,    30,    31,
+      32,    33,    34,    -1,    36,    -1,    -1,    39,     6,    -1,
+       8,     9,    44,    45,    12,    47,    -1,    -1,    16,    -1,
+      -1,    -1,    -1,    21,    -1,    23,    24,    25,    -1,    27,
+      28,    -1,    -1,    31,    -1,    -1,    -1,    -1,    36,    -1,
+      -1,    39,    -1,    -1,    -1,     3,    -1,    45,     6,     7,
+       8,     9,    -1,    51,    12,    -1,    14,    15,    16,    17,
+      18,    19,    20,    21,    -1,    23,    24,    25,    -1,    27,
+      28,    29,    30,    31,    32,    33,    34,    -1,    36,     4,
+       5,    39,    -1,    -1,    -1,    -1,    11,    45,    -1,    47,
+       4,     5,    -1,    -1,    -1,    -1,    -1,    11,    -1,     4,
+       5,    -1,    -1,    -1,    -1,    -1,    11,    -1,    -1,    -1,
+      -1,    -1,    -1,    38,    39,    40,    41,    42,    43,    -1,
+      -1,    46,    -1,    -1,    38,    39,    40,    41,    42,    43,
+      -1,    -1,    46,    38,    39,    40,    41,    42,    43,     4,
+       5,    46,     8,    -1,    -1,    -1,    11,    -1,     4,     5,
+      -1,    -1,    -1,    -1,    -1,    11,    -1,    23,    24,    25,
+      -1,    -1,    -1,    -1,    -1,    31,    -1,    -1,    -1,    -1,
+      36,    -1,    -1,    38,    39,    40,    41,    42,    43,    -1,
+      -1,    46,    38,    39,    40,    41,    42,    43,    -1,    -1,
+      46,     6,     7,     8,     9,    -1,    -1,    12,    -1,    14,
+      15,    16,    17,    18,    19,    20,    21,    -1,    23,    24,
+      25,    -1,    27,    28,    29,    30,    31,    32,    33,    34,
+      -1,    36,    -1,    -1,    39,     6,     7,     8,     9,    -1,
+      45,    12,    47,    -1,    -1,    16,    -1,    -1,    -1,    -1,
+      21,    -1,    23,    24,    25,    -1,    27,    28,    -1,    -1,
+      31,     6,    -1,     8,     9,    36,    -1,    12,    39,    -1,
+      -1,    16,    -1,    -1,    45,    -1,    21,    -1,    23,    24,
+      25,    -1,    27,    28,    -1,    -1,    31,     6,    -1,     8,
+       9,    36,    -1,    12,    39,    -1,    -1,    16,    -1,    -1,
+      45,    -1,    21,    -1,    23,    24,    25,    -1,    27,    28,
+      -1,    -1,    31,     6,    -1,     8,     9,    36,    -1,    12,
+      39,    -1,    -1,    16,    -1,    -1,    45,    -1,    21,    -1,
+      23,    24,    25,    -1,    27,    28,    -1,    -1,    31,    -1,
+       4,     5,    -1,    36,    -1,    -1,    39,    11,    -1,    -1,
+      -1,    -1,    45,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    38,    39,    40,    41,    42,    43
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,    54,     0,     1,     6,     7,     8,     9,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    23,    24,
+      25,    27,    28,    29,    30,    31,    32,    33,    34,    36,
+      39,    45,    47,    55,    57,    59,    60,    73,    83,    87,
+       3,    60,    83,    45,    50,     8,    23,    87,    37,    75,
+      45,    82,    83,    61,    45,    66,    45,    45,    45,    45,
+      68,    83,    83,     1,    58,    59,     3,    44,     4,     5,
+      11,    38,    39,    40,    41,    42,    43,    10,    12,     8,
+      79,    80,    83,    83,     8,    83,    45,    83,    45,    83,
+      83,    46,    46,     7,    69,    70,    83,    46,     3,    44,
+      48,    59,    85,    86,    83,    83,    83,    83,    83,    83,
+      83,    84,    50,    46,    49,    51,    45,    46,    81,    83,
+      46,    83,    46,    46,    49,    59,    60,    83,    83,    83,
+      51,     8,    83,     8,    40,    52,    76,    78,    44,    65,
+      67,    69,    50,    50,     8,     8,    46,    49,    62,     3,
+      56,    46,    51,    51,    50,    50,    56,     8,    40,    52,
+      81,    60,    56,    51,    51,    47,    50,     8,     8,    44,
+      22,    71,    60,     3,    88,    51,    50,    50,    63,    72,
+       3,    26,    77,    51,    51,    81,    56,    78,    74,    46,
+      60,     3,    44,    58,    64,    48,    56,    60
+};
+
+#define yyerrok                (yyerrstatus = 0)
+#define yyclearin      (yychar = YYEMPTY)
+#define YYEMPTY                (-2)
+#define YYEOF          0
+
+#define YYACCEPT       goto yyacceptlab
+#define YYABORT                goto yyabortlab
+#define YYERROR                goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL         goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                 \
+do                                                             \
+  if (yychar == YYEMPTY && yylen == 1)                         \
+    {                                                          \
+      yychar = (Token);                                                \
+      yylval = (Value);                                                \
+      yytoken = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK;                                              \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      yyerror (YY_("syntax error: cannot back up")); \
+      YYERROR;                                                 \
+    }                                                          \
+while (0)
+
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (N)                                                           \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+              (Loc).first_line, (Loc).first_column,    \
+              (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                       \
+do {                                           \
+  if (yydebug)                                 \
+    YYFPRINTF Args;                            \
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)         \
+do {                                                           \
+  if (yydebug)                                                 \
+    {                                                          \
+      YYFPRINTF (stderr, "%s ", Title);                                \
+      yysymprint (stderr,                                      \
+                  Type, Value);        \
+      YYFPRINTF (stderr, "\n");                                        \
+    }                                                          \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    short int *bottom;
+    short int *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                           \
+do {                                                           \
+  if (yydebug)                                                 \
+    yy_stack_print ((Bottom), (Top));                          \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+    int yyrule;
+#endif
+{
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
+             yyrule - 1, yylno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+    YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule)         \
+do {                                   \
+  if (yydebug)                         \
+    yy_reduce_print (Rule);            \
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef        YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      size_t yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+       switch (*++yyp)
+         {
+         case '\'':
+         case ',':
+           goto do_not_strip_quotes;
+
+         case '\\':
+           if (*++yyp != '\\')
+             goto do_not_strip_quotes;
+           /* Fall through.  */
+         default:
+           if (yyres)
+             yyres[yyn] = *yyp;
+           yyn++;
+           break;
+
+         case '"':
+           if (yyres)
+             yyres[yyn] = '\0';
+           return yyn;
+         }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* YYERROR_VERBOSE */
+
+\f
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+        break;
+    }
+}
+\f
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+    ;
+#endif
+#endif
+{
+  
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short int yyssa[YYINITDEPTH];
+  short int *yyss = yyssa;
+  short int *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;            /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+       /* Give user a chance to reallocate the stack. Use copies of
+          these so that the &'s don't force the real ones into
+          memory.  */
+       YYSTYPE *yyvs1 = yyvs;
+       short int *yyss1 = yyss;
+
+
+       /* Each stack pointer address is followed by the size of the
+          data in use in that stack, in bytes.  This used to be a
+          conditional around just the two extra args, but that might
+          be undefined if yyoverflow is a macro.  */
+       yyoverflow (YY_("memory exhausted"),
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+
+                   &yystacksize);
+
+       yyss = yyss1;
+       yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+       goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+       yystacksize = YYMAXDEPTH;
+
+      {
+       short int *yyss1 = yyss;
+       union yyalloc *yyptr =
+         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+       if (! yyptr)
+         goto yyexhaustedlab;
+       YYSTACK_RELOCATE (yyss);
+       YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+       if (yyss1 != yyssa)
+         YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                 (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+       YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a look-ahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 124 "bc.y"
+    {
+                             (yyval.i_value) = 0;
+                             if (interactive && !quiet)
+                               {
+                                 show_bc_version ();
+                                 welcome ();
+                               }
+                           }
+    break;
+
+  case 4:
+#line 135 "bc.y"
+    { run_code (); }
+    break;
+
+  case 5:
+#line 137 "bc.y"
+    { run_code (); }
+    break;
+
+  case 6:
+#line 139 "bc.y"
+    {
+                             yyerrok;
+                             init_gen ();
+                           }
+    break;
+
+  case 8:
+#line 146 "bc.y"
+    { warn ("newline not allowed"); }
+    break;
+
+  case 9:
+#line 149 "bc.y"
+    { (yyval.i_value) = 0; }
+    break;
+
+  case 13:
+#line 155 "bc.y"
+    { (yyval.i_value) = 0; }
+    break;
+
+  case 20:
+#line 164 "bc.y"
+    { (yyval.i_value) = (yyvsp[0].i_value); }
+    break;
+
+  case 21:
+#line 167 "bc.y"
+    { warranty (""); }
+    break;
+
+  case 22:
+#line 169 "bc.y"
+    { limits (); }
+    break;
+
+  case 23:
+#line 171 "bc.y"
+    {
+                             if ((yyvsp[0].i_value) & EX_COMP)
+                               warn ("comparison in expression");
+                             if ((yyvsp[0].i_value) & EX_REG)
+                               generate ("W");
+                             else 
+                               generate ("p");
+                           }
+    break;
+
+  case 24:
+#line 180 "bc.y"
+    {
+                             (yyval.i_value) = 0;
+                             generate ("w");
+                             generate ((yyvsp[0].s_value));
+                             free ((yyvsp[0].s_value));
+                           }
+    break;
+
+  case 25:
+#line 187 "bc.y"
+    {
+                             if (break_label == 0)
+                               yyerror ("Break outside a for/while");
+                             else
+                               {
+                                 sprintf (genstr, "J%1d:", break_label);
+                                 generate (genstr);
+                               }
+                           }
+    break;
+
+  case 26:
+#line 197 "bc.y"
+    {
+                             warn ("Continue statement");
+                             if (continue_label == 0)
+                               yyerror ("Continue outside a for");
+                             else
+                               {
+                                 sprintf (genstr, "J%1d:", continue_label);
+                                 generate (genstr);
+                               }
+                           }
+    break;
+
+  case 27:
+#line 208 "bc.y"
+    { exit (0); }
+    break;
+
+  case 28:
+#line 210 "bc.y"
+    { generate ("h"); }
+    break;
+
+  case 29:
+#line 212 "bc.y"
+    { generate ("R"); }
+    break;
+
+  case 30:
+#line 214 "bc.y"
+    {
+                             (yyvsp[0].i_value) = break_label; 
+                             break_label = next_label++;
+                           }
+    break;
+
+  case 31:
+#line 219 "bc.y"
+    {
+                             if ((yyvsp[-1].i_value) & EX_COMP)
+                               warn ("Comparison in first for expression");
+                             if ((yyvsp[-1].i_value) & EX_VOID)
+                               yyerror ("first expression is void");
+                             if (!((yyvsp[-1].i_value) & EX_EMPTY))
+                               generate ("p");
+                             (yyvsp[-1].i_value) = next_label++;
+                             sprintf (genstr, "N%1d:", (yyvsp[-1].i_value));
+                             generate (genstr);
+                           }
+    break;
+
+  case 32:
+#line 231 "bc.y"
+    {
+                             if ((yyvsp[-1].i_value) & EX_VOID)
+                               yyerror ("second expression is void");
+                             if ((yyvsp[-1].i_value) & EX_EMPTY ) generate ("1");
+                             (yyvsp[-1].i_value) = next_label++;
+                             sprintf (genstr, "B%1d:J%1d:", (yyvsp[-1].i_value), break_label);
+                             generate (genstr);
+                             (yyval.i_value) = continue_label;
+                             continue_label = next_label++;
+                             sprintf (genstr, "N%1d:", continue_label);
+                             generate (genstr);
+                           }
+    break;
+
+  case 33:
+#line 244 "bc.y"
+    {
+                             if ((yyvsp[-1].i_value) & EX_COMP)
+                               warn ("Comparison in third for expression");
+                             if ((yyvsp[-1].i_value) & EX_VOID)
+                               yyerror ("third expression is void");
+                             if ((yyvsp[-1].i_value) & EX_EMPTY)
+                               sprintf (genstr, "J%1d:N%1d:", (yyvsp[-7].i_value), (yyvsp[-4].i_value));
+                             else
+                               sprintf (genstr, "pJ%1d:N%1d:", (yyvsp[-7].i_value), (yyvsp[-4].i_value));
+                             generate (genstr);
+                           }
+    break;
+
+  case 34:
+#line 256 "bc.y"
+    {
+                             sprintf (genstr, "J%1d:N%1d:",
+                                      continue_label, break_label);
+                             generate (genstr);
+                             break_label = (yyvsp[-13].i_value);
+                             continue_label = (yyvsp[-5].i_value);
+                           }
+    break;
+
+  case 35:
+#line 264 "bc.y"
+    {
+                             if ((yyvsp[-1].i_value) & EX_VOID)
+                               yyerror ("void expression");
+                             (yyvsp[-1].i_value) = if_label;
+                             if_label = next_label++;
+                             sprintf (genstr, "Z%1d:", if_label);
+                             generate (genstr);
+                           }
+    break;
+
+  case 36:
+#line 273 "bc.y"
+    {
+                             sprintf (genstr, "N%1d:", if_label); 
+                             generate (genstr);
+                             if_label = (yyvsp[-5].i_value);
+                           }
+    break;
+
+  case 37:
+#line 279 "bc.y"
+    {
+                             (yyvsp[0].i_value) = next_label++;
+                             sprintf (genstr, "N%1d:", (yyvsp[0].i_value));
+                             generate (genstr);
+                           }
+    break;
+
+  case 38:
+#line 285 "bc.y"
+    {
+                             if ((yyvsp[0].i_value) & EX_VOID)
+                               yyerror ("void expression");
+                             (yyvsp[0].i_value) = break_label; 
+                             break_label = next_label++;
+                             sprintf (genstr, "Z%1d:", break_label);
+                             generate (genstr);
+                           }
+    break;
+
+  case 39:
+#line 294 "bc.y"
+    {
+                             sprintf (genstr, "J%1d:N%1d:", (yyvsp[-7].i_value), break_label);
+                             generate (genstr);
+                             break_label = (yyvsp[-4].i_value);
+                           }
+    break;
+
+  case 40:
+#line 300 "bc.y"
+    { (yyval.i_value) = 0; }
+    break;
+
+  case 41:
+#line 302 "bc.y"
+    {  warn ("print statement"); }
+    break;
+
+  case 45:
+#line 309 "bc.y"
+    {
+                             generate ("O");
+                             generate ((yyvsp[0].s_value));
+                             free ((yyvsp[0].s_value));
+                           }
+    break;
+
+  case 46:
+#line 315 "bc.y"
+    {
+                             if ((yyvsp[0].i_value) & EX_VOID)
+                               yyerror ("void expression in print");
+                             generate ("P");
+                           }
+    break;
+
+  case 48:
+#line 323 "bc.y"
+    {
+                             warn ("else clause in if statement");
+                             (yyvsp[0].i_value) = next_label++;
+                             sprintf (genstr, "J%d:N%1d:", (yyvsp[0].i_value), if_label); 
+                             generate (genstr);
+                             if_label = (yyvsp[0].i_value);
+                           }
+    break;
+
+  case 50:
+#line 334 "bc.y"
+    { char *params, *autos;
+                             /* Check auto list against parameter list? */
+                             check_params ((yyvsp[-5].a_value),(yyvsp[0].a_value));
+                             params = arg_str ((yyvsp[-5].a_value));
+                             autos  = arg_str ((yyvsp[0].a_value));
+                             set_genstr_size (30 + strlen (params)
+                                              + strlen (autos));
+                             cur_func = lookup((yyvsp[-7].s_value),FUNCTDEF);
+                             sprintf (genstr, "F%d,%s.%s[", cur_func, params,
+                                      autos); 
+                             generate (genstr);
+                             functions[cur_func].f_void = (yyvsp[-8].i_value);
+                             free_args ((yyvsp[-5].a_value));
+                             free_args ((yyvsp[0].a_value));
+                             (yyvsp[-9].i_value) = next_label;
+                             next_label = 1;
+                           }
+    break;
+
+  case 51:
+#line 352 "bc.y"
+    {
+                             generate ("0R]");
+                             next_label = (yyvsp[-12].i_value);
+                             cur_func = -1;
+                           }
+    break;
+
+  case 52:
+#line 359 "bc.y"
+    { (yyval.i_value) = 0; }
+    break;
+
+  case 53:
+#line 361 "bc.y"
+    {
+                             (yyval.i_value) = 1;
+                             warn ("void functions");
+                           }
+    break;
+
+  case 54:
+#line 367 "bc.y"
+    { (yyval.a_value) = NULL; }
+    break;
+
+  case 56:
+#line 371 "bc.y"
+    { (yyval.a_value) = NULL; }
+    break;
+
+  case 57:
+#line 373 "bc.y"
+    { (yyval.a_value) = (yyvsp[-1].a_value); }
+    break;
+
+  case 58:
+#line 375 "bc.y"
+    { (yyval.a_value) = (yyvsp[-1].a_value); }
+    break;
+
+  case 59:
+#line 378 "bc.y"
+    { (yyval.a_value) = nextarg (NULL, lookup ((yyvsp[0].s_value),SIMPLE), FALSE);}
+    break;
+
+  case 60:
+#line 380 "bc.y"
+    { (yyval.a_value) = nextarg (NULL, lookup ((yyvsp[-2].s_value),ARRAY), FALSE); }
+    break;
+
+  case 61:
+#line 382 "bc.y"
+    { (yyval.a_value) = nextarg (NULL, lookup ((yyvsp[-2].s_value),ARRAY), TRUE);
+                             warn ("Call by variable arrays");
+                           }
+    break;
+
+  case 62:
+#line 386 "bc.y"
+    { (yyval.a_value) = nextarg (NULL, lookup ((yyvsp[-2].s_value),ARRAY), TRUE);
+                             warn ("Call by variable arrays");
+                           }
+    break;
+
+  case 63:
+#line 390 "bc.y"
+    { (yyval.a_value) = nextarg ((yyvsp[-2].a_value), lookup ((yyvsp[0].s_value),SIMPLE), FALSE); }
+    break;
+
+  case 64:
+#line 392 "bc.y"
+    { (yyval.a_value) = nextarg ((yyvsp[-4].a_value), lookup ((yyvsp[-2].s_value),ARRAY), FALSE); }
+    break;
+
+  case 65:
+#line 394 "bc.y"
+    { (yyval.a_value) = nextarg ((yyvsp[-5].a_value), lookup ((yyvsp[-2].s_value),ARRAY), TRUE);
+                             warn ("Call by variable arrays");
+                           }
+    break;
+
+  case 66:
+#line 398 "bc.y"
+    { (yyval.a_value) = nextarg ((yyvsp[-5].a_value), lookup ((yyvsp[-2].s_value),ARRAY), TRUE);
+                             warn ("Call by variable arrays");
+                           }
+    break;
+
+  case 67:
+#line 403 "bc.y"
+    { (yyval.a_value) = NULL; }
+    break;
+
+  case 69:
+#line 407 "bc.y"
+    {
+                             if ((yyvsp[0].i_value) & EX_COMP)
+                               warn ("comparison in argument");
+                             if ((yyvsp[0].i_value) & EX_VOID)
+                               yyerror ("void argument");
+                             (yyval.a_value) = nextarg (NULL,0,FALSE);
+                           }
+    break;
+
+  case 70:
+#line 415 "bc.y"
+    {
+                             sprintf (genstr, "K%d:", -lookup ((yyvsp[-2].s_value),ARRAY));
+                             generate (genstr);
+                             (yyval.a_value) = nextarg (NULL,1,FALSE);
+                           }
+    break;
+
+  case 71:
+#line 421 "bc.y"
+    {
+                             if ((yyvsp[0].i_value) & EX_COMP)
+                               warn ("comparison in argument");
+                             if ((yyvsp[0].i_value) & EX_VOID)
+                               yyerror ("void argument");
+                             (yyval.a_value) = nextarg ((yyvsp[-2].a_value),0,FALSE);
+                           }
+    break;
+
+  case 72:
+#line 429 "bc.y"
+    {
+                             sprintf (genstr, "K%d:", -lookup ((yyvsp[-2].s_value),ARRAY));
+                             generate (genstr);
+                             (yyval.a_value) = nextarg ((yyvsp[-4].a_value),1,FALSE);
+                           }
+    break;
+
+  case 73:
+#line 446 "bc.y"
+    {
+                             (yyval.i_value) = EX_EMPTY;
+                             warn ("Missing expression in for statement");
+                           }
+    break;
+
+  case 75:
+#line 453 "bc.y"
+    {
+                             (yyval.i_value) = 0;
+                             generate ("0");
+                             if (cur_func == -1)
+                               yyerror("Return outside of a function.");
+                           }
+    break;
+
+  case 76:
+#line 460 "bc.y"
+    {
+                             if ((yyvsp[0].i_value) & EX_COMP)
+                               warn ("comparison in return expresion");
+                             if (!((yyvsp[0].i_value) & EX_PAREN))
+                               warn ("return expression requires parenthesis");
+                             if ((yyvsp[0].i_value) & EX_VOID)
+                               yyerror("return requires non-void expression");
+                             if (cur_func == -1)
+                               yyerror("Return outside of a function.");
+                             else if (functions[cur_func].f_void)
+                               yyerror("Return expression in a void function.");
+                           }
+    break;
+
+  case 77:
+#line 474 "bc.y"
+    {
+                             if ((yyvsp[0].c_value) != '=')
+                               {
+                                 if ((yyvsp[-1].i_value) < 0)
+                                   sprintf (genstr, "DL%d:", -(yyvsp[-1].i_value));
+                                 else
+                                   sprintf (genstr, "l%d:", (yyvsp[-1].i_value));
+                                 generate (genstr);
+                               }
+                           }
+    break;
+
+  case 78:
+#line 485 "bc.y"
+    {
+                             if ((yyvsp[0].i_value) & EX_ASSGN)
+                               warn("comparison in assignment");
+                             if ((yyvsp[0].i_value) & EX_VOID)
+                               yyerror("Assignment of a void expression");
+                             if ((yyvsp[-2].c_value) != '=')
+                               {
+                                 sprintf (genstr, "%c", (yyvsp[-2].c_value));
+                                 generate (genstr);
+                               }
+                             if ((yyvsp[-3].i_value) < 0)
+                               sprintf (genstr, "S%d:", -(yyvsp[-3].i_value));
+                             else
+                               sprintf (genstr, "s%d:", (yyvsp[-3].i_value));
+                             generate (genstr);
+                             (yyval.i_value) = EX_ASSGN;
+                           }
+    break;
+
+  case 79:
+#line 503 "bc.y"
+    {
+                             warn("&& operator");
+                             (yyvsp[0].i_value) = next_label++;
+                             sprintf (genstr, "DZ%d:p", (yyvsp[0].i_value));
+                             generate (genstr);
+                           }
+    break;
+
+  case 80:
+#line 510 "bc.y"
+    {
+                             if (((yyvsp[-3].i_value) & EX_VOID) || ((yyvsp[0].i_value) & EX_VOID))
+                               yyerror ("void expression with &&");
+                             sprintf (genstr, "DZ%d:p1N%d:", (yyvsp[-2].i_value), (yyvsp[-2].i_value));
+                             generate (genstr);
+                             (yyval.i_value) = ((yyvsp[-3].i_value) | (yyvsp[0].i_value)) & ~EX_PAREN;
+                           }
+    break;
+
+  case 81:
+#line 518 "bc.y"
+    {
+                             warn("|| operator");
+                             (yyvsp[0].i_value) = next_label++;
+                             sprintf (genstr, "B%d:", (yyvsp[0].i_value));
+                             generate (genstr);
+                           }
+    break;
+
+  case 82:
+#line 525 "bc.y"
+    {
+                             int tmplab;
+                             if (((yyvsp[-3].i_value) & EX_VOID) || ((yyvsp[0].i_value) & EX_VOID))
+                               yyerror ("void expression with ||");
+                             tmplab = next_label++;
+                             sprintf (genstr, "B%d:0J%d:N%d:1N%d:",
+                                      (yyvsp[-2].i_value), tmplab, (yyvsp[-2].i_value), tmplab);
+                             generate (genstr);
+                             (yyval.i_value) = ((yyvsp[-3].i_value) | (yyvsp[0].i_value)) & ~EX_PAREN;
+                           }
+    break;
+
+  case 83:
+#line 536 "bc.y"
+    {
+                             if ((yyvsp[0].i_value) & EX_VOID)
+                               yyerror ("void expression with !");
+                             (yyval.i_value) = (yyvsp[0].i_value) & ~EX_PAREN;
+                             warn("! operator");
+                             generate ("!");
+                           }
+    break;
+
+  case 84:
+#line 544 "bc.y"
+    {
+                             if (((yyvsp[-2].i_value) & EX_VOID) || ((yyvsp[0].i_value) & EX_VOID))
+                               yyerror ("void expression with comparison");
+                             (yyval.i_value) = EX_REG | EX_COMP;
+                             switch (*((yyvsp[-1].s_value)))
+                               {
+                               case '=':
+                                 generate ("=");
+                                 break;
+
+                               case '!':
+                                 generate ("#");
+                                 break;
+
+                               case '<':
+                                 if ((yyvsp[-1].s_value)[1] == '=')
+                                   generate ("{");
+                                 else
+                                   generate ("<");
+                                 break;
+
+                               case '>':
+                                 if ((yyvsp[-1].s_value)[1] == '=')
+                                   generate ("}");
+                                 else
+                                   generate (">");
+                                 break;
+                               }
+                           }
+    break;
+
+  case 85:
+#line 574 "bc.y"
+    {
+                             if (((yyvsp[-2].i_value) & EX_VOID) || ((yyvsp[0].i_value) & EX_VOID))
+                               yyerror ("void expression with +");
+                             generate ("+");
+                             (yyval.i_value) = ((yyvsp[-2].i_value) | (yyvsp[0].i_value)) & ~EX_PAREN;
+                           }
+    break;
+
+  case 86:
+#line 581 "bc.y"
+    {
+                             if (((yyvsp[-2].i_value) & EX_VOID) || ((yyvsp[0].i_value) & EX_VOID))
+                               yyerror ("void expression with -");
+                             generate ("-");
+                             (yyval.i_value) = ((yyvsp[-2].i_value) | (yyvsp[0].i_value)) & ~EX_PAREN;
+                           }
+    break;
+
+  case 87:
+#line 588 "bc.y"
+    {
+                             if (((yyvsp[-2].i_value) & EX_VOID) || ((yyvsp[0].i_value) & EX_VOID))
+                               yyerror ("void expression with *");
+                             generate ("*");
+                             (yyval.i_value) = ((yyvsp[-2].i_value) | (yyvsp[0].i_value)) & ~EX_PAREN;
+                           }
+    break;
+
+  case 88:
+#line 595 "bc.y"
+    {
+                             if (((yyvsp[-2].i_value) & EX_VOID) || ((yyvsp[0].i_value) & EX_VOID))
+                               yyerror ("void expression with /");
+                             generate ("/");
+                             (yyval.i_value) = ((yyvsp[-2].i_value) | (yyvsp[0].i_value)) & ~EX_PAREN;
+                           }
+    break;
+
+  case 89:
+#line 602 "bc.y"
+    {
+                             if (((yyvsp[-2].i_value) & EX_VOID) || ((yyvsp[0].i_value) & EX_VOID))
+                               yyerror ("void expression with %");
+                             generate ("%");
+                             (yyval.i_value) = ((yyvsp[-2].i_value) | (yyvsp[0].i_value)) & ~EX_PAREN;
+                           }
+    break;
+
+  case 90:
+#line 609 "bc.y"
+    {
+                             if (((yyvsp[-2].i_value) & EX_VOID) || ((yyvsp[0].i_value) & EX_VOID))
+                               yyerror ("void expression with ^");
+                             generate ("^");
+                             (yyval.i_value) = ((yyvsp[-2].i_value) | (yyvsp[0].i_value)) & ~EX_PAREN;
+                           }
+    break;
+
+  case 91:
+#line 616 "bc.y"
+    {
+                             if ((yyvsp[0].i_value) & EX_VOID)
+                               yyerror ("void expression with unary -");
+                             generate ("n");
+                             (yyval.i_value) = (yyvsp[0].i_value) & ~EX_PAREN;
+                           }
+    break;
+
+  case 92:
+#line 623 "bc.y"
+    {
+                             (yyval.i_value) = EX_REG;
+                             if ((yyvsp[0].i_value) < 0)
+                               sprintf (genstr, "L%d:", -(yyvsp[0].i_value));
+                             else
+                               sprintf (genstr, "l%d:", (yyvsp[0].i_value));
+                             generate (genstr);
+                           }
+    break;
+
+  case 93:
+#line 632 "bc.y"
+    {
+                             int len = strlen((yyvsp[0].s_value));
+                             (yyval.i_value) = EX_REG;
+                             if (len == 1 && *(yyvsp[0].s_value) == '0')
+                               generate ("0");
+                             else if (len == 1 && *(yyvsp[0].s_value) == '1')
+                               generate ("1");
+                             else
+                               {
+                                 generate ("K");
+                                 generate ((yyvsp[0].s_value));
+                                 generate (":");
+                               }
+                             free ((yyvsp[0].s_value));
+                           }
+    break;
+
+  case 94:
+#line 648 "bc.y"
+    { 
+                             if ((yyvsp[-1].i_value) & EX_VOID)
+                               yyerror ("void expression in parenthesis");
+                             (yyval.i_value) = (yyvsp[-1].i_value) | EX_REG | EX_PAREN;
+                           }
+    break;
+
+  case 95:
+#line 654 "bc.y"
+    { int fn;
+                             fn = lookup ((yyvsp[-3].s_value),FUNCT);
+                             if (functions[fn].f_void)
+                               (yyval.i_value) = EX_VOID;
+                             else
+                               (yyval.i_value) = EX_REG;
+                             if ((yyvsp[-1].a_value) != NULL)
+                               { char *params = call_str ((yyvsp[-1].a_value));
+                                 set_genstr_size (20 + strlen (params));
+                                 sprintf (genstr, "C%d,%s:", fn, params);
+                                 free_args ((yyvsp[-1].a_value));
+                               }
+                             else
+                               {
+                                 sprintf (genstr, "C%d:", fn);
+                               }
+                             generate (genstr);
+                           }
+    break;
+
+  case 96:
+#line 673 "bc.y"
+    {
+                             (yyval.i_value) = EX_REG;
+                             if ((yyvsp[0].i_value) < 0)
+                               {
+                                 if ((yyvsp[-1].c_value) == '+')
+                                   sprintf (genstr, "DA%d:L%d:", -(yyvsp[0].i_value), -(yyvsp[0].i_value));
+                                 else
+                                   sprintf (genstr, "DM%d:L%d:", -(yyvsp[0].i_value), -(yyvsp[0].i_value));
+                               }
+                             else
+                               {
+                                 if ((yyvsp[-1].c_value) == '+')
+                                   sprintf (genstr, "i%d:l%d:", (yyvsp[0].i_value), (yyvsp[0].i_value));
+                                 else
+                                   sprintf (genstr, "d%d:l%d:", (yyvsp[0].i_value), (yyvsp[0].i_value));
+                               }
+                             generate (genstr);
+                           }
+    break;
+
+  case 97:
+#line 692 "bc.y"
+    {
+                             (yyval.i_value) = EX_REG;
+                             if ((yyvsp[-1].i_value) < 0)
+                               {
+                                 sprintf (genstr, "DL%d:x", -(yyvsp[-1].i_value));
+                                 generate (genstr); 
+                                 if ((yyvsp[0].c_value) == '+')
+                                   sprintf (genstr, "A%d:", -(yyvsp[-1].i_value));
+                                 else
+                                     sprintf (genstr, "M%d:", -(yyvsp[-1].i_value));
+                               }
+                             else
+                               {
+                                 sprintf (genstr, "l%d:", (yyvsp[-1].i_value));
+                                 generate (genstr);
+                                 if ((yyvsp[0].c_value) == '+')
+                                   sprintf (genstr, "i%d:", (yyvsp[-1].i_value));
+                                 else
+                                   sprintf (genstr, "d%d:", (yyvsp[-1].i_value));
+                               }
+                             generate (genstr);
+                           }
+    break;
+
+  case 98:
+#line 715 "bc.y"
+    {
+                             if ((yyvsp[-1].i_value) & EX_VOID)
+                               yyerror ("void expression in length()");
+                             generate ("cL");
+                             (yyval.i_value) = EX_REG;
+                           }
+    break;
+
+  case 99:
+#line 722 "bc.y"
+    {
+                             if ((yyvsp[-1].i_value) & EX_VOID)
+                               yyerror ("void expression in sqrt()");
+                             generate ("cR");
+                             (yyval.i_value) = EX_REG;
+                           }
+    break;
+
+  case 100:
+#line 729 "bc.y"
+    {
+                             if ((yyvsp[-1].i_value) & EX_VOID)
+                               yyerror ("void expression in scale()");
+                             generate ("cS");
+                             (yyval.i_value) = EX_REG;
+                           }
+    break;
+
+  case 101:
+#line 736 "bc.y"
+    {
+                             warn ("read function");
+                             generate ("cI");
+                             (yyval.i_value) = EX_REG;
+                           }
+    break;
+
+  case 102:
+#line 742 "bc.y"
+    {
+                             warn ("random function");
+                             generate ("cX");
+                             (yyval.i_value) = EX_REG;
+                           }
+    break;
+
+  case 103:
+#line 749 "bc.y"
+    { (yyval.i_value) = lookup((yyvsp[0].s_value),SIMPLE); }
+    break;
+
+  case 104:
+#line 751 "bc.y"
+    {
+                             if ((yyvsp[-1].i_value) & EX_VOID)
+                               yyerror("void expression as subscript");
+                             if ((yyvsp[-1].i_value) & EX_COMP)
+                               warn("comparison in subscript");
+                             (yyval.i_value) = lookup((yyvsp[-3].s_value),ARRAY);
+                           }
+    break;
+
+  case 105:
+#line 759 "bc.y"
+    { (yyval.i_value) = 0; }
+    break;
+
+  case 106:
+#line 761 "bc.y"
+    { (yyval.i_value) = 1; }
+    break;
+
+  case 107:
+#line 763 "bc.y"
+    { (yyval.i_value) = 2; }
+    break;
+
+  case 108:
+#line 765 "bc.y"
+    { (yyval.i_value) = 3;
+                             warn ("History variable");
+                           }
+    break;
+
+  case 109:
+#line 769 "bc.y"
+    { (yyval.i_value) = 4;
+                             warn ("Last variable");
+                           }
+    break;
+
+  case 110:
+#line 775 "bc.y"
+    { warn ("End of line required"); }
+    break;
+
+  case 112:
+#line 778 "bc.y"
+    { warn ("Too many end of lines"); }
+    break;
+
+
+      default: break;
+    }
+
+/* Line 1126 of yacc.c.  */
+#line 2350 "bc.c"
+\f
+  yyvsp -= yylen;
+  yyssp -= yylen;
+
+
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+       {
+         int yytype = YYTRANSLATE (yychar);
+         YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+         YYSIZE_T yysize = yysize0;
+         YYSIZE_T yysize1;
+         int yysize_overflow = 0;
+         char *yymsg = 0;
+#        define YYERROR_VERBOSE_ARGS_MAXIMUM 5
+         char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+         int yyx;
+
+#if 0
+         /* This is so xgettext sees the translatable formats that are
+            constructed on the fly.  */
+         YY_("syntax error, unexpected %s");
+         YY_("syntax error, unexpected %s, expecting %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+#endif
+         char *yyfmt;
+         char const *yyf;
+         static char const yyunexpected[] = "syntax error, unexpected %s";
+         static char const yyexpecting[] = ", expecting %s";
+         static char const yyor[] = " or %s";
+         char yyformat[sizeof yyunexpected
+                       + sizeof yyexpecting - 1
+                       + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+                          * (sizeof yyor - 1))];
+         char const *yyprefix = yyexpecting;
+
+         /* Start YYX at -YYN if negative to avoid negative indexes in
+            YYCHECK.  */
+         int yyxbegin = yyn < 0 ? -yyn : 0;
+
+         /* Stay within bounds of both yycheck and yytname.  */
+         int yychecklim = YYLAST - yyn;
+         int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+         int yycount = 1;
+
+         yyarg[0] = yytname[yytype];
+         yyfmt = yystpcpy (yyformat, yyunexpected);
+
+         for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+           if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+             {
+               if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                 {
+                   yycount = 1;
+                   yysize = yysize0;
+                   yyformat[sizeof yyunexpected - 1] = '\0';
+                   break;
+                 }
+               yyarg[yycount++] = yytname[yyx];
+               yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+               yysize_overflow |= yysize1 < yysize;
+               yysize = yysize1;
+               yyfmt = yystpcpy (yyfmt, yyprefix);
+               yyprefix = yyor;
+             }
+
+         yyf = YY_(yyformat);
+         yysize1 = yysize + yystrlen (yyf);
+         yysize_overflow |= yysize1 < yysize;
+         yysize = yysize1;
+
+         if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
+           yymsg = (char *) YYSTACK_ALLOC (yysize);
+         if (yymsg)
+           {
+             /* Avoid sprintf, as that infringes on the user's name space.
+                Don't have undefined behavior even if the translation
+                produced a string with the wrong number of "%s"s.  */
+             char *yyp = yymsg;
+             int yyi = 0;
+             while ((*yyp = *yyf))
+               {
+                 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+                   {
+                     yyp += yytnamerr (yyp, yyarg[yyi++]);
+                     yyf += 2;
+                   }
+                 else
+                   {
+                     yyp++;
+                     yyf++;
+                   }
+               }
+             yyerror (yymsg);
+             YYSTACK_FREE (yymsg);
+           }
+         else
+           {
+             yyerror (YY_("syntax error"));
+             goto yyexhaustedlab;
+           }
+       }
+      else
+#endif /* YYERROR_VERBOSE */
+       yyerror (YY_("syntax error"));
+    }
+
+
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+        error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+         /* Return failure if at end of input.  */
+         if (yychar == YYEOF)
+           YYABORT;
+        }
+      else
+       {
+         yydestruct ("Error: discarding", yytoken, &yylval);
+         yychar = YYEMPTY;
+       }
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (0)
+     goto yyerrorlab;
+
+yyvsp -= yylen;
+  yyssp -= yylen;
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+       {
+         yyn += YYTERROR;
+         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+           {
+             yyn = yytable[yyn];
+             if (0 < yyn)
+               break;
+           }
+       }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+       YYABORT;
+
+
+      yydestruct ("Error: popping", yystos[yystate], yyvsp);
+      YYPOPSTACK;
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* Shift the error token. */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+                yytoken, &yylval);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                 yystos[*yyssp], yyvsp);
+      YYPOPSTACK;
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+#line 781 "bc.y"
+
+
+
diff --git a/bc/bc.h b/bc/bc.h
new file mode 100644 (file)
index 0000000..464d715
--- /dev/null
+++ b/bc/bc.h
@@ -0,0 +1,127 @@
+/* A Bison parser, made by GNU Bison 2.1.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ENDOFLINE = 258,
+     AND = 259,
+     OR = 260,
+     NOT = 261,
+     STRING = 262,
+     NAME = 263,
+     NUMBER = 264,
+     ASSIGN_OP = 265,
+     REL_OP = 266,
+     INCR_DECR = 267,
+     Define = 268,
+     Break = 269,
+     Quit = 270,
+     Length = 271,
+     Return = 272,
+     For = 273,
+     If = 274,
+     While = 275,
+     Sqrt = 276,
+     Else = 277,
+     Scale = 278,
+     Ibase = 279,
+     Obase = 280,
+     Auto = 281,
+     Read = 282,
+     Random = 283,
+     Warranty = 284,
+     Halt = 285,
+     Last = 286,
+     Continue = 287,
+     Print = 288,
+     Limits = 289,
+     UNARY_MINUS = 290,
+     HistoryVar = 291,
+     Void = 292
+   };
+#endif
+/* Tokens.  */
+#define ENDOFLINE 258
+#define AND 259
+#define OR 260
+#define NOT 261
+#define STRING 262
+#define NAME 263
+#define NUMBER 264
+#define ASSIGN_OP 265
+#define REL_OP 266
+#define INCR_DECR 267
+#define Define 268
+#define Break 269
+#define Quit 270
+#define Length 271
+#define Return 272
+#define For 273
+#define If 274
+#define While 275
+#define Sqrt 276
+#define Else 277
+#define Scale 278
+#define Ibase 279
+#define Obase 280
+#define Auto 281
+#define Read 282
+#define Random 283
+#define Warranty 284
+#define Halt 285
+#define Last 286
+#define Continue 287
+#define Print 288
+#define Limits 289
+#define UNARY_MINUS 290
+#define HistoryVar 291
+#define Void 292
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 54 "bc.y"
+typedef union YYSTYPE {
+       char     *s_value;
+       char      c_value;
+       int       i_value;
+       arg_list *a_value;
+       } YYSTYPE;
+/* Line 1447 of yacc.c.  */
+#line 119 "bc.h"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE yylval;
+
+
+
diff --git a/bc/bc.y b/bc/bc.y
new file mode 100644 (file)
index 0000000..14dc4be
--- /dev/null
+++ b/bc/bc.y
@@ -0,0 +1,782 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* bc.y: The grammar for a POSIX compatable bc processor with some
+         extensions to the language. */
+
+%{
+
+#include "bcdefs.h"
+#include "global.h"
+#include "proto.h"
+
+/* current function number. */
+int cur_func = -1;
+
+/* Expression encoded information -- See comment at expression rules. */
+#define EX_ASSGN 0 
+#define EX_REG   1
+#define EX_COMP  2
+#define EX_PAREN 4
+#define EX_VOID  8 
+#define EX_EMPTY 16
+
+%}
+
+%start program
+
+%union {
+       char     *s_value;
+       char      c_value;
+       int       i_value;
+       arg_list *a_value;
+       }
+
+/* Extensions over POSIX bc.
+   a) NAME was LETTER.  This grammar allows longer names.
+      Single letter names will still work.
+   b) Relational_expression allowed only one comparison.
+      This grammar has added boolean expressions with
+      && (and) || (or) and ! (not) and allowed all of them in
+      full expressions.
+   c) Added an else to the if.
+   d) Call by variable array parameters
+   e) read() procedure that reads a number under program control from stdin.
+   f) halt statement that halts the the program under program control.  It
+      is an executed statement.
+   g) continue statement for for loops.
+   h) optional expressions in the for loop.
+   i) print statement to print multiple numbers per line.
+   j) warranty statement to print an extended warranty notice.
+   j) limits statement to print the processor's limits.
+*/
+
+%token <i_value> ENDOFLINE AND OR NOT
+%token <s_value> STRING NAME NUMBER
+/*     '-', '+' are tokens themselves          */
+/*     '=', '+=',  '-=', '*=', '/=', '%=', '^=' */
+%token <c_value> ASSIGN_OP
+/*     '==', '<=', '>=', '!=', '<', '>'        */
+%token <s_value> REL_OP
+/*     '++', '--'                              */
+%token <c_value> INCR_DECR
+/*     'define', 'break', 'quit', 'length'     */
+%token <i_value> Define    Break    Quit    Length
+/*     'return', 'for', 'if', 'while', 'sqrt', 'else'  */
+%token <i_value> Return    For    If    While    Sqrt   Else
+/*     'scale', 'ibase', 'obase', 'auto', 'read', 'random'     */
+%token <i_value> Scale Ibase Obase Auto    Read    Random
+/*     'warranty', 'halt', 'last', 'continue', 'print', 'limits'   */
+%token <i_value> Warranty  Halt  Last  Continue  Print  Limits
+/*     'history', 'void' */
+%token <i_value> UNARY_MINUS HistoryVar Void
+
+
+/* Types of all other things. */
+%type <i_value> expression return_expression named_expression opt_expression
+%type <c_value> '+' '-' '*' '/' '%' 
+%type <a_value> opt_parameter_list opt_auto_define_list define_list
+%type <a_value> opt_argument_list argument_list
+%type <i_value> program input_item semicolon_list statement_list
+%type <i_value> statement function statement_or_error required_eol
+%type <i_value> opt_void
+
+/* precedence */
+%left OR
+%left AND
+%nonassoc NOT
+%left REL_OP
+%right ASSIGN_OP
+%left '+' '-'
+%left '*' '/' '%'
+%right '^'
+%nonassoc UNARY_MINUS
+%nonassoc INCR_DECR
+
+%%
+program                        : /* empty */
+                           {
+                             $$ = 0;
+                             if (interactive && !quiet)
+                               {
+                                 show_bc_version ();
+                                 welcome ();
+                               }
+                           }
+                       | program input_item
+                       ;
+input_item             : semicolon_list ENDOFLINE
+                           { run_code (); }
+                       | function
+                           { run_code (); }
+                       | error ENDOFLINE
+                           {
+                             yyerrok;
+                             init_gen ();
+                           }
+                       ;
+opt_newline            : /* empty */
+                       | ENDOFLINE
+                           { warn ("newline not allowed"); }
+                       ;
+semicolon_list         : /* empty */
+                           { $$ = 0; }
+                       | statement_or_error
+                       | semicolon_list ';' statement_or_error
+                       | semicolon_list ';'
+                       ;
+statement_list         : /* empty */
+                           { $$ = 0; }
+                       | statement_or_error
+                       | statement_list ENDOFLINE
+                       | statement_list ENDOFLINE statement_or_error
+                       | statement_list ';'
+                       | statement_list ';' statement
+                       ;
+statement_or_error     : statement
+                       | error statement
+                           { $$ = $2; }
+                       ;
+statement              : Warranty
+                           { warranty (""); }
+                       | Limits
+                           { limits (); }
+                       | expression
+                           {
+                             if ($1 & EX_COMP)
+                               warn ("comparison in expression");
+                             if ($1 & EX_REG)
+                               generate ("W");
+                             else 
+                               generate ("p");
+                           }
+                       | STRING
+                           {
+                             $$ = 0;
+                             generate ("w");
+                             generate ($1);
+                             free ($1);
+                           }
+                       | Break
+                           {
+                             if (break_label == 0)
+                               yyerror ("Break outside a for/while");
+                             else
+                               {
+                                 sprintf (genstr, "J%1d:", break_label);
+                                 generate (genstr);
+                               }
+                           }
+                       | Continue
+                           {
+                             warn ("Continue statement");
+                             if (continue_label == 0)
+                               yyerror ("Continue outside a for");
+                             else
+                               {
+                                 sprintf (genstr, "J%1d:", continue_label);
+                                 generate (genstr);
+                               }
+                           }
+                       | Quit
+                           { exit (0); }
+                       | Halt
+                           { generate ("h"); }
+                       | Return return_expression
+                           { generate ("R"); }
+                       | For 
+                           {
+                             $1 = break_label; 
+                             break_label = next_label++;
+                           }
+                         '(' opt_expression ';'
+                           {
+                             if ($4 & EX_COMP)
+                               warn ("Comparison in first for expression");
+                             if ($4 & EX_VOID)
+                               yyerror ("first expression is void");
+                             if (!($4 & EX_EMPTY))
+                               generate ("p");
+                             $4 = next_label++;
+                             sprintf (genstr, "N%1d:", $4);
+                             generate (genstr);
+                           }
+                         opt_expression ';'
+                           {
+                             if ($7 & EX_VOID)
+                               yyerror ("second expression is void");
+                             if ($7 & EX_EMPTY ) generate ("1");
+                             $7 = next_label++;
+                             sprintf (genstr, "B%1d:J%1d:", $7, break_label);
+                             generate (genstr);
+                             $<i_value>$ = continue_label;
+                             continue_label = next_label++;
+                             sprintf (genstr, "N%1d:", continue_label);
+                             generate (genstr);
+                           }
+                         opt_expression ')'
+                           {
+                             if ($10 & EX_COMP)
+                               warn ("Comparison in third for expression");
+                             if ($10 & EX_VOID)
+                               yyerror ("third expression is void");
+                             if ($10 & EX_EMPTY)
+                               sprintf (genstr, "J%1d:N%1d:", $4, $7);
+                             else
+                               sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
+                             generate (genstr);
+                           }
+                         opt_newline statement
+                           {
+                             sprintf (genstr, "J%1d:N%1d:",
+                                      continue_label, break_label);
+                             generate (genstr);
+                             break_label = $1;
+                             continue_label = $<i_value>9;
+                           }
+                       | If '(' expression ')' 
+                           {
+                             if ($3 & EX_VOID)
+                               yyerror ("void expression");
+                             $3 = if_label;
+                             if_label = next_label++;
+                             sprintf (genstr, "Z%1d:", if_label);
+                             generate (genstr);
+                           }
+                         opt_newline statement  opt_else
+                           {
+                             sprintf (genstr, "N%1d:", if_label); 
+                             generate (genstr);
+                             if_label = $3;
+                           }
+                       | While 
+                           {
+                             $1 = next_label++;
+                             sprintf (genstr, "N%1d:", $1);
+                             generate (genstr);
+                           }
+                       '(' expression 
+                           {
+                             if ($4 & EX_VOID)
+                               yyerror ("void expression");
+                             $4 = break_label; 
+                             break_label = next_label++;
+                             sprintf (genstr, "Z%1d:", break_label);
+                             generate (genstr);
+                           }
+                       ')' opt_newline statement
+                           {
+                             sprintf (genstr, "J%1d:N%1d:", $1, break_label);
+                             generate (genstr);
+                             break_label = $4;
+                           }
+                       | '{' statement_list '}'
+                           { $$ = 0; }
+                       | Print
+                           {  warn ("print statement"); }
+                         print_list
+                       ;
+print_list             : print_element
+                       | print_element ',' print_list
+                       ;
+print_element          : STRING
+                           {
+                             generate ("O");
+                             generate ($1);
+                             free ($1);
+                           }
+                       | expression
+                           {
+                             if ($1 & EX_VOID)
+                               yyerror ("void expression in print");
+                             generate ("P");
+                           }
+                       ;
+opt_else               : /* nothing */
+                       | Else 
+                           {
+                             warn ("else clause in if statement");
+                             $1 = next_label++;
+                             sprintf (genstr, "J%d:N%1d:", $1, if_label); 
+                             generate (genstr);
+                             if_label = $1;
+                           }
+                         opt_newline statement
+                       ;
+function               : Define opt_void NAME '(' opt_parameter_list ')' opt_newline
+                         '{' required_eol opt_auto_define_list 
+                           { char *params, *autos;
+                             /* Check auto list against parameter list? */
+                             check_params ($5,$10);
+                             params = arg_str ($5);
+                             autos  = arg_str ($10);
+                             set_genstr_size (30 + strlen (params)
+                                              + strlen (autos));
+                             cur_func = lookup($3,FUNCTDEF);
+                             sprintf (genstr, "F%d,%s.%s[", cur_func, params,
+                                      autos); 
+                             generate (genstr);
+                             functions[cur_func].f_void = $2;
+                             free_args ($5);
+                             free_args ($10);
+                             $1 = next_label;
+                             next_label = 1;
+                           }
+                         statement_list /* ENDOFLINE */ '}'
+                           {
+                             generate ("0R]");
+                             next_label = $1;
+                             cur_func = -1;
+                           }
+                       ;
+opt_void               : /* empty */
+                           { $$ = 0; }
+                       | Void
+                           {
+                             $$ = 1;
+                             warn ("void functions");
+                           }
+                       ;
+opt_parameter_list     : /* empty */ 
+                           { $$ = NULL; }
+                       | define_list
+                       ;
+opt_auto_define_list   : /* empty */ 
+                           { $$ = NULL; }
+                       | Auto define_list ENDOFLINE
+                           { $$ = $2; } 
+                       | Auto define_list ';'
+                           { $$ = $2; } 
+                       ;
+define_list            : NAME
+                           { $$ = nextarg (NULL, lookup ($1,SIMPLE), FALSE);}
+                       | NAME '[' ']'
+                           { $$ = nextarg (NULL, lookup ($1,ARRAY), FALSE); }
+                       | '*' NAME '[' ']'
+                           { $$ = nextarg (NULL, lookup ($2,ARRAY), TRUE);
+                             warn ("Call by variable arrays");
+                           }
+                       | '&' NAME '[' ']'
+                           { $$ = nextarg (NULL, lookup ($2,ARRAY), TRUE);
+                             warn ("Call by variable arrays");
+                           }
+                       | define_list ',' NAME
+                           { $$ = nextarg ($1, lookup ($3,SIMPLE), FALSE); }
+                       | define_list ',' NAME '[' ']'
+                           { $$ = nextarg ($1, lookup ($3,ARRAY), FALSE); }
+                       | define_list ',' '*' NAME '[' ']'
+                           { $$ = nextarg ($1, lookup ($4,ARRAY), TRUE);
+                             warn ("Call by variable arrays");
+                           }
+                       | define_list ',' '&' NAME '[' ']'
+                           { $$ = nextarg ($1, lookup ($4,ARRAY), TRUE);
+                             warn ("Call by variable arrays");
+                           }
+                       ;
+opt_argument_list      : /* empty */
+                           { $$ = NULL; }
+                       | argument_list
+                       ;
+argument_list          : expression
+                           {
+                             if ($1 & EX_COMP)
+                               warn ("comparison in argument");
+                             if ($1 & EX_VOID)
+                               yyerror ("void argument");
+                             $$ = nextarg (NULL,0,FALSE);
+                           }
+                       | NAME '[' ']'
+                           {
+                             sprintf (genstr, "K%d:", -lookup ($1,ARRAY));
+                             generate (genstr);
+                             $$ = nextarg (NULL,1,FALSE);
+                           }
+                       | argument_list ',' expression
+                           {
+                             if ($3 & EX_COMP)
+                               warn ("comparison in argument");
+                             if ($3 & EX_VOID)
+                               yyerror ("void argument");
+                             $$ = nextarg ($1,0,FALSE);
+                           }
+                       | argument_list ',' NAME '[' ']'
+                           {
+                             sprintf (genstr, "K%d:", -lookup ($3,ARRAY));
+                             generate (genstr);
+                             $$ = nextarg ($1,1,FALSE);
+                           }
+                       ;
+
+/* Expression lval meanings!  (Bits mean something!)  (See defines above)
+ *  0 => Top op is assignment.
+ *  1 => Top op is not assignment.
+ *  2 => Comparison is somewhere in expression.
+ *  4 => Expression is in parenthesis.
+ *  8 => Expression is void!
+ * 16 => Empty optional expression.
+ */
+
+opt_expression                 : /* empty */
+                           {
+                             $$ = EX_EMPTY;
+                             warn ("Missing expression in for statement");
+                           }
+                       | expression
+                       ;
+return_expression      : /* empty */
+                           {
+                             $$ = 0;
+                             generate ("0");
+                             if (cur_func == -1)
+                               yyerror("Return outside of a function.");
+                           }
+                       | expression
+                           {
+                             if ($1 & EX_COMP)
+                               warn ("comparison in return expresion");
+                             if (!($1 & EX_PAREN))
+                               warn ("return expression requires parenthesis");
+                             if ($1 & EX_VOID)
+                               yyerror("return requires non-void expression");
+                             if (cur_func == -1)
+                               yyerror("Return outside of a function.");
+                             else if (functions[cur_func].f_void)
+                               yyerror("Return expression in a void function.");
+                           }
+                       ;
+expression             :  named_expression ASSIGN_OP 
+                           {
+                             if ($2 != '=')
+                               {
+                                 if ($1 < 0)
+                                   sprintf (genstr, "DL%d:", -$1);
+                                 else
+                                   sprintf (genstr, "l%d:", $1);
+                                 generate (genstr);
+                               }
+                           }
+                         expression
+                           {
+                             if ($4 & EX_ASSGN)
+                               warn("comparison in assignment");
+                             if ($4 & EX_VOID)
+                               yyerror("Assignment of a void expression");
+                             if ($2 != '=')
+                               {
+                                 sprintf (genstr, "%c", $2);
+                                 generate (genstr);
+                               }
+                             if ($1 < 0)
+                               sprintf (genstr, "S%d:", -$1);
+                             else
+                               sprintf (genstr, "s%d:", $1);
+                             generate (genstr);
+                             $$ = EX_ASSGN;
+                           }
+                       | expression AND 
+                           {
+                             warn("&& operator");
+                             $2 = next_label++;
+                             sprintf (genstr, "DZ%d:p", $2);
+                             generate (genstr);
+                           }
+                         expression
+                           {
+                             if (($1 & EX_VOID) || ($4 & EX_VOID))
+                               yyerror ("void expression with &&");
+                             sprintf (genstr, "DZ%d:p1N%d:", $2, $2);
+                             generate (genstr);
+                             $$ = ($1 | $4) & ~EX_PAREN;
+                           }
+                       | expression OR
+                           {
+                             warn("|| operator");
+                             $2 = next_label++;
+                             sprintf (genstr, "B%d:", $2);
+                             generate (genstr);
+                           }
+                         expression
+                           {
+                             int tmplab;
+                             if (($1 & EX_VOID) || ($4 & EX_VOID))
+                               yyerror ("void expression with ||");
+                             tmplab = next_label++;
+                             sprintf (genstr, "B%d:0J%d:N%d:1N%d:",
+                                      $2, tmplab, $2, tmplab);
+                             generate (genstr);
+                             $$ = ($1 | $4) & ~EX_PAREN;
+                           }
+                       | NOT expression
+                           {
+                             if ($2 & EX_VOID)
+                               yyerror ("void expression with !");
+                             $$ = $2 & ~EX_PAREN;
+                             warn("! operator");
+                             generate ("!");
+                           }
+                       | expression REL_OP expression
+                           {
+                             if (($1 & EX_VOID) || ($3 & EX_VOID))
+                               yyerror ("void expression with comparison");
+                             $$ = EX_REG | EX_COMP;
+                             switch (*($2))
+                               {
+                               case '=':
+                                 generate ("=");
+                                 break;
+
+                               case '!':
+                                 generate ("#");
+                                 break;
+
+                               case '<':
+                                 if ($2[1] == '=')
+                                   generate ("{");
+                                 else
+                                   generate ("<");
+                                 break;
+
+                               case '>':
+                                 if ($2[1] == '=')
+                                   generate ("}");
+                                 else
+                                   generate (">");
+                                 break;
+                               }
+                           }
+                       | expression '+' expression
+                           {
+                             if (($1 & EX_VOID) || ($3 & EX_VOID))
+                               yyerror ("void expression with +");
+                             generate ("+");
+                             $$ = ($1 | $3) & ~EX_PAREN;
+                           }
+                       | expression '-' expression
+                           {
+                             if (($1 & EX_VOID) || ($3 & EX_VOID))
+                               yyerror ("void expression with -");
+                             generate ("-");
+                             $$ = ($1 | $3) & ~EX_PAREN;
+                           }
+                       | expression '*' expression
+                           {
+                             if (($1 & EX_VOID) || ($3 & EX_VOID))
+                               yyerror ("void expression with *");
+                             generate ("*");
+                             $$ = ($1 | $3) & ~EX_PAREN;
+                           }
+                       | expression '/' expression
+                           {
+                             if (($1 & EX_VOID) || ($3 & EX_VOID))
+                               yyerror ("void expression with /");
+                             generate ("/");
+                             $$ = ($1 | $3) & ~EX_PAREN;
+                           }
+                       | expression '%' expression
+                           {
+                             if (($1 & EX_VOID) || ($3 & EX_VOID))
+                               yyerror ("void expression with %");
+                             generate ("%");
+                             $$ = ($1 | $3) & ~EX_PAREN;
+                           }
+                       | expression '^' expression
+                           {
+                             if (($1 & EX_VOID) || ($3 & EX_VOID))
+                               yyerror ("void expression with ^");
+                             generate ("^");
+                             $$ = ($1 | $3) & ~EX_PAREN;
+                           }
+                       | '-' expression  %prec UNARY_MINUS
+                           {
+                             if ($2 & EX_VOID)
+                               yyerror ("void expression with unary -");
+                             generate ("n");
+                             $$ = $2 & ~EX_PAREN;
+                           }
+                       | named_expression
+                           {
+                             $$ = EX_REG;
+                             if ($1 < 0)
+                               sprintf (genstr, "L%d:", -$1);
+                             else
+                               sprintf (genstr, "l%d:", $1);
+                             generate (genstr);
+                           }
+                       | NUMBER
+                           {
+                             int len = strlen($1);
+                             $$ = EX_REG;
+                             if (len == 1 && *$1 == '0')
+                               generate ("0");
+                             else if (len == 1 && *$1 == '1')
+                               generate ("1");
+                             else
+                               {
+                                 generate ("K");
+                                 generate ($1);
+                                 generate (":");
+                               }
+                             free ($1);
+                           }
+                       | '(' expression ')'
+                           { 
+                             if ($2 & EX_VOID)
+                               yyerror ("void expression in parenthesis");
+                             $$ = $2 | EX_REG | EX_PAREN;
+                           }
+                       | NAME '(' opt_argument_list ')'
+                           { int fn;
+                             fn = lookup ($1,FUNCT);
+                             if (functions[fn].f_void)
+                               $$ = EX_VOID;
+                             else
+                               $$ = EX_REG;
+                             if ($3 != NULL)
+                               { char *params = call_str ($3);
+                                 set_genstr_size (20 + strlen (params));
+                                 sprintf (genstr, "C%d,%s:", fn, params);
+                                 free_args ($3);
+                               }
+                             else
+                               {
+                                 sprintf (genstr, "C%d:", fn);
+                               }
+                             generate (genstr);
+                           }
+                       | INCR_DECR named_expression
+                           {
+                             $$ = EX_REG;
+                             if ($2 < 0)
+                               {
+                                 if ($1 == '+')
+                                   sprintf (genstr, "DA%d:L%d:", -$2, -$2);
+                                 else
+                                   sprintf (genstr, "DM%d:L%d:", -$2, -$2);
+                               }
+                             else
+                               {
+                                 if ($1 == '+')
+                                   sprintf (genstr, "i%d:l%d:", $2, $2);
+                                 else
+                                   sprintf (genstr, "d%d:l%d:", $2, $2);
+                               }
+                             generate (genstr);
+                           }
+                       | named_expression INCR_DECR
+                           {
+                             $$ = EX_REG;
+                             if ($1 < 0)
+                               {
+                                 sprintf (genstr, "DL%d:x", -$1);
+                                 generate (genstr); 
+                                 if ($2 == '+')
+                                   sprintf (genstr, "A%d:", -$1);
+                                 else
+                                     sprintf (genstr, "M%d:", -$1);
+                               }
+                             else
+                               {
+                                 sprintf (genstr, "l%d:", $1);
+                                 generate (genstr);
+                                 if ($2 == '+')
+                                   sprintf (genstr, "i%d:", $1);
+                                 else
+                                   sprintf (genstr, "d%d:", $1);
+                               }
+                             generate (genstr);
+                           }
+                       | Length '(' expression ')'
+                           {
+                             if ($3 & EX_VOID)
+                               yyerror ("void expression in length()");
+                             generate ("cL");
+                             $$ = EX_REG;
+                           }
+                       | Sqrt '(' expression ')'
+                           {
+                             if ($3 & EX_VOID)
+                               yyerror ("void expression in sqrt()");
+                             generate ("cR");
+                             $$ = EX_REG;
+                           }
+                       | Scale '(' expression ')'
+                           {
+                             if ($3 & EX_VOID)
+                               yyerror ("void expression in scale()");
+                             generate ("cS");
+                             $$ = EX_REG;
+                           }
+                       | Read '(' ')'
+                           {
+                             warn ("read function");
+                             generate ("cI");
+                             $$ = EX_REG;
+                           }
+                       | Random '(' ')'
+                           {
+                             warn ("random function");
+                             generate ("cX");
+                             $$ = EX_REG;
+                           }
+                       ;
+named_expression       : NAME
+                           { $$ = lookup($1,SIMPLE); }
+                       | NAME '[' expression ']'
+                           {
+                             if ($3 & EX_VOID)
+                               yyerror("void expression as subscript");
+                             if ($3 & EX_COMP)
+                               warn("comparison in subscript");
+                             $$ = lookup($1,ARRAY);
+                           }
+                       | Ibase
+                           { $$ = 0; }
+                       | Obase
+                           { $$ = 1; }
+                       | Scale
+                           { $$ = 2; }
+                       | HistoryVar
+                           { $$ = 3;
+                             warn ("History variable");
+                           }
+                       | Last
+                           { $$ = 4;
+                             warn ("Last variable");
+                           }
+                       ;
+
+
+required_eol           : { warn ("End of line required"); }
+                       | ENDOFLINE
+                       | required_eol ENDOFLINE
+                         { warn ("Too many end of lines"); }
+                       ;
+
+%%
+
diff --git a/bc/bcdefs.h b/bc/bcdefs.h
new file mode 100644 (file)
index 0000000..29c4d52
--- /dev/null
@@ -0,0 +1,202 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* bcdefs.h:  The single file to include all constants and type definitions. */
+
+/* Include the configuration file. */
+#include "config.h"
+
+/* Standard includes for all files. */
+#include <stdio.h>
+#include <sys/types.h>
+#include <ctype.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#if defined(LIBEDIT)
+#include <histedit.h>
+#endif
+
+#if defined(READLINE)
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+
+/* Initialization magic ... */
+#ifdef _GLOBAL_C
+#define EXTERN 
+#define INIT(x) = x
+#else
+#define EXTERN extern
+#define INIT(x)
+#endif
+
+/* Include the other definitions. */
+#include "const.h"
+#include "number.h"
+
+/* These definitions define all the structures used in
+   code and data storage.  This includes the representation of
+   labels.   The "guiding" principle is to make structures that
+   take a minimum of space when unused but can be built to contain
+   the full structures.  */
+
+/* Labels are first.  Labels are generated sequentially in functions
+   and full code.  They just "point" to a single bye in the code.  The
+   "address" is the byte number.  The byte number is used to get an
+   actual character pointer. */
+
+typedef struct bc_label_group
+    {
+      long l_adrs [ BC_LABEL_GROUP ];
+      struct bc_label_group *l_next;
+    } bc_label_group;
+
+/* Argument list.  Recorded in the function so arguments can
+   be checked at call time. */
+
+typedef struct arg_list
+    {
+      int av_name;
+      int arg_is_var;          /* Extension ... variable parameters. */
+      struct arg_list *next;
+    } arg_list;
+
+/* Each function has its own code segments and labels.  There can be
+   no jumps between functions so labels are unique to a function. */
+
+typedef struct 
+    {
+      char f_defined;   /* Is this function defined yet. */
+      char f_void;     /* Is this function a void function. */
+      char *f_body;
+      int  f_body_size;  /* Size of body.  Power of 2. */
+      int  f_code_size;
+      bc_label_group *f_label;
+      arg_list *f_params;
+      arg_list *f_autos;
+    } bc_function;
+
+/* Code addresses. */
+typedef struct {
+      int pc_func;
+      int pc_addr;
+    } program_counter;
+
+
+/* Variables are "pushable" (auto) and thus we need a stack mechanism.
+   This is built into the variable record. */
+
+typedef struct bc_var
+    {
+      bc_num v_value;
+      struct bc_var *v_next;
+    }  bc_var;
+
+
+/* bc arrays can also be "auto" variables and thus need the same
+   kind of stacking mechanisms. */
+
+typedef struct bc_array_node
+    {
+      union
+       {
+         bc_num n_num [NODE_SIZE];
+         struct bc_array_node *n_down [NODE_SIZE];
+       } n_items;
+    } bc_array_node;
+
+typedef struct bc_array
+    {
+      bc_array_node *a_tree;
+      short a_depth;
+    } bc_array;
+
+typedef struct bc_var_array
+    {
+      bc_array *a_value;
+      char      a_param;
+      struct bc_var_array *a_next;
+    } bc_var_array;
+
+
+/* For the stacks, execution and function, we need records to allow
+   for arbitrary size. */
+
+typedef struct estack_rec {
+       bc_num s_num;
+       struct estack_rec *s_next;
+} estack_rec;
+
+typedef struct fstack_rec {
+       int  s_val;
+       struct fstack_rec *s_next;
+} fstack_rec;
+
+
+/* The following are for the name tree. */
+
+typedef struct id_rec {
+       char  *id;      /* The program name. */
+                       /* A name == 0 => nothing assigned yet. */
+       int   a_name;   /* The array variable name (number). */
+       int   f_name;   /* The function name (number).  */
+       int   v_name;   /* The variable name (number).  */
+        short balance;  /* For the balanced tree. */
+       struct id_rec *left, *right; /* Tree pointers. */
+} id_rec;
+
+
+/* A list of files to process. */
+
+typedef struct file_node {
+       char *name;
+       struct file_node *next;
+} file_node;
+
+/* Macro Definitions */
+
+#if defined(LIBEDIT)
+#define HISTORY_SIZE(n) history(hist, &histev, H_SETSIZE, n)
+#define UNLIMIT_HISTORY history(hist, &histev, H_SETSIZE, INT_MAX)
+#endif
+
+#if defined(READLINE)
+#define HISTORY_SIZE(n) stifle_history(n)
+#define UNLIMIT_HISTORY unstifle_history()
+#endif
+
+/* Now the global variable declarations. */
+#include "global.h"
diff --git a/bc/const.h b/bc/const.h
new file mode 100644 (file)
index 0000000..1b3040b
--- /dev/null
@@ -0,0 +1,97 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* const.h: Constants for bc. */
+
+/* Define INT_MAX and LONG_MAX if not defined.  Assuming 32 bits... */
+
+#ifndef INT_MAX
+#define INT_MAX 0x7FFFFFFF
+#endif
+#ifndef LONG_MAX
+#define LONG_MAX 0x7FFFFFFF
+#endif
+
+
+/* Define constants in some reasonable size.  The next 4 constants are
+   POSIX constants. */
+
+#ifdef BC_BASE_MAX
+  /* <limits.h> on a POSIX.2 system may have defined these.  Override. */
+# undef BC_BASE_MAX
+# undef BC_SCALE_MAX
+# undef BC_STRING_MAX
+# undef BC_DIM_MAX
+#endif
+
+#define BC_BASE_MAX   INT_MAX
+#define BC_SCALE_MAX  INT_MAX
+#define BC_STRING_MAX INT_MAX
+
+
+/* Definitions for arrays. */
+
+#define BC_DIM_MAX   16777215     /* this should be NODE_SIZE^NODE_DEPTH-1 */
+
+#define   NODE_SIZE        64     /* Must be a power of 2. */
+#define   NODE_MASK      0x3f     /* Must be NODE_SIZE-1. */
+#define   NODE_SHIFT        6     /* Number of 1 bits in NODE_MASK. */
+#define   NODE_DEPTH        4
+
+
+/* Other BC limits defined but not part of POSIX. */
+
+#define BC_LABEL_GROUP 64
+#define BC_LABEL_LOG    6
+#define BC_START_SIZE  1024    /* Initial code body size. */
+
+/* Maximum number of variables, arrays and functions and the
+   allocation increment for the dynamic arrays. */
+
+#define MAX_STORE   32767
+#define STORE_INCR     32
+
+/* Other interesting constants. */
+
+#define FALSE 0
+#define TRUE  1
+
+/* for use with lookup (). */
+#define SIMPLE   0
+#define ARRAY    1
+#define FUNCT    2
+#define FUNCTDEF 3
+
+#ifdef __STDC__
+#define CONST const
+#define VOID  void
+#else
+#define CONST
+#define VOID
+#endif
diff --git a/bc/execute.c b/bc/execute.c
new file mode 100644 (file)
index 0000000..e4e8ef7
--- /dev/null
@@ -0,0 +1,793 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+/* execute.c - run a bc program. */
+
+#include "bcdefs.h"
+#include <signal.h>
+#include "proto.h"
+
+
+/* The SIGINT interrupt handling routine. */
+
+int had_sigint;
+
+void
+stop_execution (sig)
+     int sig;
+{
+  had_sigint = TRUE;
+}
+
+
+/* Get the current byte and advance the PC counter. */
+
+unsigned char
+byte (p)
+     program_counter *p;
+{
+  return (functions[p->pc_func].f_body[p->pc_addr++]);
+}
+
+
+/* The routine that actually runs the machine. */
+
+void
+execute ()
+{
+  int label_num, l_gp, l_off;
+  bc_label_group *gp;
+  
+  char inst, ch;
+  int  new_func;
+  int  var_name;
+
+  int const_base;
+
+  bc_num temp_num;
+  arg_list *auto_list;
+
+  /* Initialize this run... */
+  pc.pc_func = 0;
+  pc.pc_addr = 0;
+  runtime_error = FALSE;
+  bc_init_num (&temp_num);
+
+  /* Set up the interrupt mechanism for an interactive session. */
+  if (interactive)
+    {
+      signal (SIGINT, stop_execution);
+    }
+   
+  had_sigint = FALSE;
+  while (pc.pc_addr < functions[pc.pc_func].f_code_size
+        && !runtime_error && !had_sigint)
+    {
+      inst = byte(&pc);
+
+#if DEBUG > 3
+      { /* Print out address and the stack before each instruction.*/
+       int depth; estack_rec *temp = ex_stack;
+       
+       printf ("func=%d addr=%d inst=%c\n",pc.pc_func, pc.pc_addr, inst);
+       if (temp == NULL) printf ("empty stack.\n", inst);
+       else
+         {
+           depth = 1;
+           while (temp != NULL)
+             {
+               printf ("  %d = ", depth);
+               bc_out_num (temp->s_num, 10, out_char, std_only);
+               depth++;
+               temp = temp->s_next;
+             }
+           out_char ('\n');
+         }
+      }
+#endif
+
+    switch ( inst )
+      {
+
+      case 'A' : /* increment array variable (Add one). */
+       var_name = byte(&pc);
+       if ((var_name & 0x80) != 0)
+         var_name = ((var_name & 0x7f) << 8) + byte(&pc);
+       incr_array (var_name);
+       break;
+
+      case 'B' : /* Branch to a label if TOS != 0. Remove value on TOS. */
+      case 'Z' : /* Branch to a label if TOS == 0. Remove value on TOS. */
+       c_code = !bc_is_zero (ex_stack->s_num);
+       pop ();
+      case 'J' : /* Jump to a label. */
+       label_num = byte(&pc);  /* Low order bits first. */
+       label_num += byte(&pc) << 8;
+       if (inst == 'J' || (inst == 'B' && c_code)
+           || (inst == 'Z' && !c_code)) {
+         gp = functions[pc.pc_func].f_label;
+         l_gp  = label_num >> BC_LABEL_LOG;
+         l_off = label_num % BC_LABEL_GROUP;
+         while (l_gp-- > 0) gp = gp->l_next;
+         pc.pc_addr = gp->l_adrs[l_off];
+       }
+       break;
+
+      case 'C' : /* Call a function. */
+       /* Get the function number. */
+       new_func = byte(&pc);
+       if ((new_func & 0x80) != 0) 
+         new_func = ((new_func & 0x7f) << 8) + byte(&pc);
+
+       /* Check to make sure it is defined. */
+       if (!functions[new_func].f_defined)
+         {
+           rt_error ("Function %s not defined.", f_names[new_func]);
+           break;
+         }
+
+       /* Check and push parameters. */
+       process_params (&pc, new_func);
+
+       /* Push auto variables. */
+       for (auto_list = functions[new_func].f_autos;
+            auto_list != NULL;
+            auto_list = auto_list->next)
+         auto_var (auto_list->av_name);
+
+       /* Push pc and ibase. */
+       fpush (pc.pc_func);
+       fpush (pc.pc_addr);
+       fpush (i_base);
+
+       /* Reset pc to start of function. */
+       pc.pc_func = new_func;
+       pc.pc_addr = 0;
+       break;
+
+      case 'D' : /* Duplicate top of stack */
+       push_copy (ex_stack->s_num);
+       break;
+
+      case 'K' : /* Push a constant */
+       /* Get the input base and convert it to a bc number. */
+       if (pc.pc_func == 0) 
+         const_base = i_base;
+       else
+         const_base = fn_stack->s_val;
+       if (const_base == 10)
+         push_b10_const (&pc);
+       else
+         push_constant (prog_char, const_base);
+       break;
+
+      case 'L' : /* load array variable */
+       var_name = byte(&pc);
+       if ((var_name & 0x80) != 0)
+         var_name = ((var_name & 0x7f) << 8) + byte(&pc);
+       load_array (var_name);
+       break;
+
+      case 'M' : /* decrement array variable (Minus!) */
+       var_name = byte(&pc);
+       if ((var_name & 0x80) != 0)
+         var_name = ((var_name & 0x7f) << 8) + byte(&pc);
+       decr_array (var_name);
+       break;
+
+      case 'O' : /* Write a string to the output with processing. */
+       while ((ch = byte(&pc)) != '"')
+         if (ch != '\\')
+           out_schar (ch);
+         else
+           {
+             ch = byte(&pc);
+             if (ch == '"') break;
+             switch (ch)
+               {
+               case 'a':  out_schar (007); break;
+               case 'b':  out_schar ('\b'); break;
+               case 'f':  out_schar ('\f'); break;
+               case 'n':  out_schar ('\n'); break;
+               case 'q':  out_schar ('"'); break;
+               case 'r':  out_schar ('\r'); break;
+               case 't':  out_schar ('\t'); break;
+               case '\\': out_schar ('\\'); break;
+               default:  break;
+               }
+           }
+       fflush (stdout);
+       break;
+
+      case 'R' : /* Return from function */
+       if (pc.pc_func != 0)
+         {
+           /* "Pop" autos and parameters. */
+           pop_vars(functions[pc.pc_func].f_autos);
+           pop_vars(functions[pc.pc_func].f_params);
+           /* reset the pc. */
+           fpop ();
+           pc.pc_addr = fpop ();
+           pc.pc_func = fpop ();
+         }
+       else
+         rt_error ("Return from main program.");
+       break;
+
+      case 'S' : /* store array variable */
+       var_name = byte(&pc);
+       if ((var_name & 0x80) != 0)
+         var_name = ((var_name & 0x7f ) << 8) + byte(&pc);
+       store_array (var_name);
+       break;
+
+      case 'T' : /* Test tos for zero */
+       c_code = bc_is_zero (ex_stack->s_num);
+       assign (c_code);
+       break;
+
+      case 'W' : /* Write the value on the top of the stack. */
+      case 'P' : /* Write the value on the top of the stack.  No newline. */
+       bc_out_num (ex_stack->s_num, o_base, out_char, std_only);
+       if (inst == 'W') out_char ('\n');
+       store_var (4);  /* Special variable "last". */
+       fflush (stdout);
+       pop ();
+       break;
+
+      case 'c' : /* Call special function. */
+       new_func = byte(&pc);
+
+      switch (new_func)
+       {
+       case 'L':  /* Length function. */
+         /* For the number 0.xxxx,  0 is not significant. */
+         if (ex_stack->s_num->n_len == 1 &&
+             ex_stack->s_num->n_scale != 0 &&
+             ex_stack->s_num->n_value[0] == 0 )
+           bc_int2num (&ex_stack->s_num, ex_stack->s_num->n_scale);
+         else
+           bc_int2num (&ex_stack->s_num, ex_stack->s_num->n_len
+                    + ex_stack->s_num->n_scale);
+         break;
+               
+       case 'S':  /* Scale function. */ 
+         bc_int2num (&ex_stack->s_num, ex_stack->s_num->n_scale);
+         break;
+
+       case 'R':  /* Square Root function. */
+         if (!bc_sqrt (&ex_stack->s_num, scale))
+           rt_error ("Square root of a negative number");
+         break;
+
+       case 'I': /* Read function. */
+         push_constant (input_char, i_base);
+         break;
+
+       case 'X': /* Random function. */
+         push_copy (_zero_);
+         bc_int2num (&ex_stack->s_num, random());
+         break;
+       }
+       break;
+
+      case 'd' : /* Decrement number */
+       var_name = byte(&pc);
+       if ((var_name & 0x80) != 0)
+         var_name = ((var_name & 0x7f) << 8) + byte(&pc);
+       decr_var (var_name);
+       break;
+      
+      case 'h' : /* Halt the machine. */
+       exit (0);
+
+      case 'i' : /* increment number */
+       var_name = byte(&pc);
+       if ((var_name & 0x80) != 0)
+         var_name = ((var_name & 0x7f) << 8) + byte(&pc);
+       incr_var (var_name);
+       break;
+
+      case 'l' : /* load variable */
+       var_name = byte(&pc);
+       if ((var_name & 0x80) != 0)
+         var_name = ((var_name & 0x7f) << 8) + byte(&pc);
+       load_var (var_name);
+       break;
+
+      case 'n' : /* Negate top of stack. */
+       bc_sub (_zero_, ex_stack->s_num, &ex_stack->s_num, 0);
+       break;
+
+      case 'p' : /* Pop the execution stack. */
+       pop ();
+       break;
+
+      case 's' : /* store variable */
+       var_name = byte(&pc);
+       if ((var_name & 0x80) != 0)
+         var_name = ((var_name & 0x7f) << 8) + byte(&pc);
+       store_var (var_name);
+       break;
+
+      case 'w' : /* Write a string to the output. */
+       while ((ch = byte(&pc)) != '"') out_schar (ch);
+       fflush (stdout);
+       break;
+                  
+      case 'x' : /* Exchange Top of Stack with the one under the tos. */
+       if (check_stack(2)) {
+         bc_num temp = ex_stack->s_num;
+         ex_stack->s_num = ex_stack->s_next->s_num;
+         ex_stack->s_next->s_num = temp;
+       }
+       break;
+
+      case '0' : /* Load Constant 0. */
+       push_copy (_zero_);
+       break;
+
+      case '1' : /* Load Constant 1. */
+       push_copy (_one_);
+       break;
+
+      case '!' : /* Negate the boolean value on top of the stack. */
+       c_code = bc_is_zero (ex_stack->s_num);
+       assign (c_code);
+       break;
+
+      case '&' : /* compare greater than */
+       if (check_stack(2))
+         {
+           c_code = !bc_is_zero (ex_stack->s_next->s_num)
+             && !bc_is_zero (ex_stack->s_num);
+           pop ();
+           assign (c_code);
+         }
+       break;
+
+      case '|' : /* compare greater than */
+       if (check_stack(2))
+         {
+           c_code = !bc_is_zero (ex_stack->s_next->s_num)
+             || !bc_is_zero (ex_stack->s_num);
+           pop ();
+           assign (c_code);
+         }
+       break;
+
+      case '+' : /* add */
+       if (check_stack(2))
+         {
+           bc_add (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num, 0);
+           pop();
+           pop();
+           push_num (temp_num);
+           bc_init_num (&temp_num);
+         }
+       break;
+
+      case '-' : /* subtract */
+       if (check_stack(2))
+         {
+           bc_sub (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num, 0);
+           pop();
+           pop();
+           push_num (temp_num);
+           bc_init_num (&temp_num);
+         }
+       break;
+
+      case '*' : /* multiply */
+       if (check_stack(2))
+         {
+           bc_multiply (ex_stack->s_next->s_num, ex_stack->s_num,
+                        &temp_num, scale);
+           pop();
+           pop();
+           push_num (temp_num);
+           bc_init_num (&temp_num);
+         }
+       break;
+
+      case '/' : /* divide */
+       if (check_stack(2))
+         {
+           if (bc_divide (ex_stack->s_next->s_num,
+                          ex_stack->s_num, &temp_num, scale) == 0)
+             {
+               pop();
+               pop();
+               push_num (temp_num);
+               bc_init_num (&temp_num);
+             }
+           else
+             rt_error ("Divide by zero");
+         }
+       break;
+
+      case '%' : /* remainder */
+       if (check_stack(2))
+         {
+           if (bc_is_zero (ex_stack->s_num))
+             rt_error ("Modulo by zero");
+           else
+             {
+               bc_modulo (ex_stack->s_next->s_num,
+                          ex_stack->s_num, &temp_num, scale);
+               pop();
+               pop();
+               push_num (temp_num);
+               bc_init_num (&temp_num);
+             }
+         }
+       break;
+
+      case '^' : /* raise */
+       if (check_stack(2))
+         {
+           bc_raise (ex_stack->s_next->s_num,
+                     ex_stack->s_num, &temp_num, scale);
+           if (bc_is_zero (ex_stack->s_next->s_num) && bc_is_neg (ex_stack->s_num))
+             rt_error ("divide by zero");
+           pop();
+           pop();
+           push_num (temp_num);
+           bc_init_num (&temp_num);
+         }
+       break;
+
+      case '=' : /* compare equal */
+       if (check_stack(2))
+         {
+           c_code = bc_compare (ex_stack->s_next->s_num,
+                                ex_stack->s_num) == 0;
+           pop ();
+           assign (c_code);
+         }
+       break;
+
+      case '#' : /* compare not equal */
+       if (check_stack(2))
+         {
+           c_code = bc_compare (ex_stack->s_next->s_num,
+                                ex_stack->s_num) != 0;
+           pop ();
+           assign (c_code);
+         }
+       break;
+
+      case '<' : /* compare less than */
+       if (check_stack(2))
+         {
+           c_code = bc_compare (ex_stack->s_next->s_num,
+                                ex_stack->s_num) == -1;
+           pop ();
+           assign (c_code);
+         }
+       break;
+
+      case '{' : /* compare less than or equal */
+       if (check_stack(2))
+         {
+           c_code = bc_compare (ex_stack->s_next->s_num,
+                                ex_stack->s_num) <= 0;
+           pop ();
+           assign (c_code);
+         }
+       break;
+
+      case '>' : /* compare greater than */
+       if (check_stack(2))
+         {
+           c_code = bc_compare (ex_stack->s_next->s_num,
+                                ex_stack->s_num) == 1;
+           pop ();
+           assign (c_code);
+         }
+       break;
+
+      case '}' : /* compare greater than or equal */
+       if (check_stack(2))
+         {
+           c_code = bc_compare (ex_stack->s_next->s_num,
+                                ex_stack->s_num) >= 0;
+           pop ();
+           assign (c_code);
+         }
+       break;
+
+       default  : /* error! */
+         rt_error ("bad instruction: inst=%c", inst);
+      }
+    }
+
+  /* Clean up the function stack and pop all autos/parameters. */
+  while (pc.pc_func != 0)
+    {
+      pop_vars(functions[pc.pc_func].f_autos);
+      pop_vars(functions[pc.pc_func].f_params);
+      fpop ();
+      pc.pc_addr = fpop ();
+      pc.pc_func = fpop ();
+    }
+
+  /* Clean up the execution stack. */ 
+  while (ex_stack != NULL) pop();
+
+  /* Clean up the interrupt stuff. */
+  if (interactive)
+    {
+      signal (SIGINT, use_quit);
+      if (had_sigint)
+       printf ("\ninterrupted execution.\n");
+    }
+}
+
+
+/* Prog_char gets another byte from the program.  It is used for
+   conversion of text constants in the code to numbers. */
+
+int
+prog_char ()
+{
+  return (int) byte(&pc);
+}
+
+
+/* Read a character from the standard input.  This function is used
+   by the "read" function. */
+
+int
+input_char ()
+{
+  int in_ch;
+  
+  /* Get a character from the standard input for the read function. */
+  in_ch = getchar();
+
+  /* Check for a \ quoted newline. */
+  if (in_ch == '\\')
+    {
+      in_ch = getchar();
+      if (in_ch == '\n') {
+         in_ch = getchar();
+         out_col = 0;  /* Saw a new line */
+       }
+    }
+
+  /* Classify and preprocess the input character. */
+  if (isdigit(in_ch))
+    return (in_ch - '0');
+  if (in_ch >= 'A' && in_ch <= 'F')
+    return (in_ch + 10 - 'A');
+  if (in_ch >= 'a' && in_ch <= 'f')
+    return (in_ch + 10 - 'a');
+  if (in_ch == '.' || in_ch == '+' || in_ch == '-')
+    return (in_ch);
+  if (in_ch <= ' ')
+    return (' ');
+  
+  return (':');
+}
+
+
+/* Push_constant converts a sequence of input characters as returned
+   by IN_CHAR into a number.  The number is pushed onto the execution
+   stack.  The number is converted as a number in base CONV_BASE. */
+
+void
+push_constant (in_char, conv_base)
+   int (*in_char)(VOID);
+   int conv_base;
+{
+  int digits;
+  bc_num build, temp, result, mult, divisor;
+  int   in_ch, first_ch;
+  char  negative;
+
+  /* Initialize all bc numbers */
+  bc_init_num (&temp);
+  bc_init_num (&result);
+  bc_init_num (&mult);
+  build = bc_copy_num (_zero_);
+  negative = FALSE;
+
+  /* The conversion base. */
+  bc_int2num (&mult, conv_base);
+  
+  /* Get things ready. */
+  in_ch = in_char();
+  while (in_ch == ' ')
+    in_ch = in_char();
+
+  if (in_ch == '+')
+    in_ch = in_char();
+  else
+    if (in_ch == '-')
+      {
+       negative = TRUE;
+       in_ch = in_char();
+      }
+
+  /* Check for the special case of a single digit. */
+  if (in_ch < 16)
+    {
+      first_ch = in_ch;
+      in_ch = in_char();
+      if (in_ch < 16 && first_ch >= conv_base)
+       first_ch = conv_base - 1;
+      bc_int2num (&build, (int) first_ch);
+    }
+
+  /* Convert the integer part. */
+  while (in_ch < 16)
+    {
+      if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1;
+      bc_multiply (build, mult, &result, 0);
+      bc_int2num (&temp, (int) in_ch);
+      bc_add (result, temp, &build, 0);
+      in_ch = in_char();
+    }
+  if (in_ch == '.')
+    {
+      in_ch = in_char();
+      if (in_ch >= conv_base) in_ch = conv_base-1;
+      bc_free_num (&result);
+      bc_free_num (&temp);
+      divisor = bc_copy_num (_one_);
+      result = bc_copy_num (_zero_);
+      digits = 0;
+      while (in_ch < 16)
+       {
+         bc_multiply (result, mult, &result, 0);
+         bc_int2num (&temp, (int) in_ch);
+         bc_add (result, temp, &result, 0);
+         bc_multiply (divisor, mult, &divisor, 0);
+         digits++;
+         in_ch = in_char();
+         if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1;
+       }
+      bc_divide (result, divisor, &result, digits);
+      bc_add (build, result, &build, 0);
+    }
+  
+  /* Final work.  */
+  if (negative)
+    bc_sub (_zero_, build, &build, 0);
+
+  push_num (build);
+  bc_free_num (&temp);
+  bc_free_num (&result);
+  bc_free_num (&mult);
+}
+
+
+/* When converting base 10 constants from the program, we use this
+   more efficient way to convert them to numbers.  PC tells where
+   the constant starts and is expected to be advanced to after
+   the constant. */
+
+void
+push_b10_const (progctr)
+     program_counter *progctr;
+{
+  bc_num build;
+  program_counter look_pc;
+  int kdigits, kscale;
+  unsigned char inchar;
+  char *ptr;
+  
+  /* Count the digits and get things ready. */
+  look_pc = *progctr;
+  kdigits = 0;
+  kscale  = 0;
+  inchar = byte (&look_pc);
+  while (inchar != '.' && inchar != ':')
+    {
+      kdigits++;
+      inchar = byte(&look_pc);
+    }
+  if (inchar == '.' )
+    {
+      inchar = byte(&look_pc);
+      while (inchar != ':')
+       {
+         kscale++;
+         inchar = byte(&look_pc);
+       }
+    }
+
+  /* Get the first character again and move the progctr. */
+  inchar = byte(progctr);
+  
+  /* Secial cases of 0, 1, and A-F single inputs. */
+  if (kdigits == 1 && kscale == 0)
+    {
+      if (inchar == 0)
+       {
+         push_copy (_zero_);
+         inchar = byte(progctr);
+         return;
+       }
+      if (inchar == 1) {
+      push_copy (_one_);
+      inchar = byte(progctr);
+      return;
+    }
+    if (inchar > 9)
+      {
+       bc_init_num (&build);
+       bc_int2num (&build, inchar);
+       push_num (build);
+       inchar = byte(progctr);
+       return;
+      }
+    }
+
+  /* Build the new number. */
+  if (kdigits == 0)
+    {
+      build = bc_new_num (1,kscale);
+      ptr = build->n_value;
+      *ptr++ = 0;
+    }
+  else
+    {
+      build = bc_new_num (kdigits,kscale);
+      ptr = build->n_value;
+    }
+
+  while (inchar != ':')
+    {
+      if (inchar != '.')
+       {
+         if (inchar > 9)
+           *ptr++ = 9;
+         else
+           *ptr++ = inchar;
+       }
+      inchar = byte(progctr);
+    }
+  push_num (build);
+}
+
+
+/* Put the correct value on the stack for C_CODE.  Frees TOS num. */
+
+void
+assign (code)
+     char code;
+{
+  bc_free_num (&ex_stack->s_num);
+  if (code)
+    ex_stack->s_num = bc_copy_num (_one_);
+  else
+    ex_stack->s_num = bc_copy_num (_zero_);
+}
+
diff --git a/bc/fix-libmath_h b/bc/fix-libmath_h
new file mode 100755 (executable)
index 0000000..f973a8c
--- /dev/null
@@ -0,0 +1,9 @@
+ed libmath.h <<EOS-EOS
+1,1s/^/{"/
+1,\$s/\$/",/
+2,\$s/^/"/
+\$,\$d
+\$,\$s/,\$/,0}/
+w
+q
+EOS-EOS
diff --git a/bc/global.c b/bc/global.c
new file mode 100644 (file)
index 0000000..a388a0c
--- /dev/null
@@ -0,0 +1,40 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* global.c:  This defines the global variables. */
+
+/* We are global.c ... so define and initialize variables here. */
+
+#define _GLOBAL_C
+
+#include "bcdefs.h"
+
+CONST char *libmath[] = 
+#include "libmath.h"
+;
diff --git a/bc/global.h b/bc/global.h
new file mode 100644 (file)
index 0000000..706abd0
--- /dev/null
@@ -0,0 +1,155 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* global.h:  The global variables for bc.  */
+
+/* The current break level's lable. */
+EXTERN int break_label;
+
+/* The current if statement's else label or label after else. */
+EXTERN int if_label;
+
+/* The current for statement label for continuing the loop. */
+EXTERN int continue_label;
+
+/* Next available label number. */
+EXTERN int next_label;
+
+/* Byte code character storage.  Used in many places for generation of code. */
+EXTERN char  *genstr  INIT(NULL);
+EXTERN int    genlen  INIT(0);
+
+/* Count of characters printed to the output in compile_only mode. */
+EXTERN int out_count;
+
+/* Have we generated any code since the last initialization of the code
+   generator.  */
+EXTERN char did_gen;
+
+/* Is this run an interactive execution.  (Is stdin a terminal?) */
+EXTERN char interactive  INIT(FALSE);
+
+/* Just generate the byte code.  -c flag. */
+EXTERN int compile_only INIT(FALSE);
+
+/* Load the standard math functions.  -l flag. */
+EXTERN int use_math  INIT(FALSE);
+
+/* Give a warning on use of any non-standard feature (non-POSIX).  -w flag. */
+EXTERN int warn_not_std  INIT(FALSE);
+
+/* Accept POSIX bc only!  -s flag. */
+EXTERN int std_only  INIT(FALSE);
+
+/* Don't print the banner at start up.  -q flag. */
+EXTERN int quiet  INIT(FALSE);
+
+/* The list of file names to process. */
+EXTERN file_node *file_names  INIT(NULL);
+
+/* The name of the current file being processed. */
+EXTERN char *file_name;
+
+/* Is the current file a named file or standard input? */
+EXTERN char   is_std_in;
+
+/* global variables for the bc machine. All will be dynamic in size.*/
+/* Function storage. main is (0) and functions (1-f_count) */
+
+EXTERN bc_function *functions;
+EXTERN char **f_names;
+EXTERN int  f_count;
+
+/* Variable stoarge and reverse names. */
+
+EXTERN bc_var **variables;
+EXTERN char **v_names;
+EXTERN int  v_count;
+
+/* Array Variable storage and reverse names. */
+
+EXTERN bc_var_array **arrays;
+EXTERN char **a_names;
+EXTERN int  a_count;
+
+/* Execution stack. */
+EXTERN estack_rec *ex_stack;
+
+/* Function return stack. */
+EXTERN fstack_rec *fn_stack;
+
+/* Current ibase, obase, scale, and n_history (if needed). */
+EXTERN int i_base;
+EXTERN int o_base;
+EXTERN int scale;
+#if defined(READLINE) || defined(LIBEDIT)
+EXTERN int n_history;
+#endif
+
+#if defined(LIBEDIT)
+/* LIBEDIT data */
+EditLine *edit INIT(NULL);
+History  *hist;
+HistEvent histev;
+#endif
+
+/* "Condition code" -- false (0) or true (1) */
+EXTERN char c_code;
+
+/* Records the number of the runtime error. */
+EXTERN char runtime_error;
+
+/* Holds the current location of execution. */
+EXTERN program_counter pc;
+
+/* For POSIX bc, this is just for number output, not strings. */
+EXTERN int out_col;
+
+/* Keeps track of the current number of characters per output line.
+   This includes the \n at the end of the line. */
+EXTERN int line_size;
+
+/* Input Line numbers and other error information. */
+EXTERN int line_no;
+EXTERN int had_error;
+
+/* For larger identifiers, a tree, and how many "storage" locations
+   have been allocated. */
+
+EXTERN int next_array;
+EXTERN int next_func;
+EXTERN int next_var;
+
+EXTERN id_rec *name_tree;
+
+/* For use with getopt.  Do not declare them here.*/
+extern int optind;
+
+/* Access to the yy input file.  Defined in scan.c. */
+extern FILE *yyin;
diff --git a/bc/libmath.b b/bc/libmath.b
new file mode 100644 (file)
index 0000000..64f3002
--- /dev/null
@@ -0,0 +1,338 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* libmath.b for bc.  */
+
+scale = 20
+
+/* Uses the fact that e^x = (e^(x/2))^2
+   When x is small enough, we use the series:
+     e^x = 1 + x + x^2/2! + x^3/3! + ...
+*/
+
+define e(x) {
+  auto  a, b, d, e, f, i, m, n, v, z
+
+  /* a - holds x^y of x^y/y! */
+  /* d - holds y! */
+  /* e - is the value x^y/y! */
+  /* v - is the sum of the e's */
+  /* f - number of times x was divided by 2. */
+  /* m - is 1 if x was minus. */
+  /* i - iteration count. */
+  /* n - the scale to compute the sum. */
+  /* z - orignal scale. */
+  /* b - holds the original ibase. */
+
+  /* Non base 10 ibase? */
+  if (ibase != A) {
+     b = ibase;
+     ibase = A;
+     v = e(x);
+     ibase = b;
+     return (v);
+  }
+
+  /* Check the sign of x. */
+  if (x<0) {
+    m = 1
+    x = -x
+  } 
+
+  /* Precondition x. */
+  z = scale;
+  n = 6 + z + .44*x;
+  scale = scale(x)+1;
+  while (x > 1) {
+    f += 1;
+    x /= 2;
+    scale += 1;
+  }
+
+  /* Initialize the variables. */
+  scale = n;
+  v = 1+x
+  a = x
+  d = 1
+
+  for (i=2; 1; i++) {
+    e = (a *= x) / (d *= i)
+    if (e == 0) {
+      if (f>0) while (f--)  v = v*v;
+      scale = z
+      if (m) return (1/v);
+      return (v/1);
+    }
+    v += e
+  }
+}
+
+/* Natural log. Uses the fact that ln(x^2) = 2*ln(x)
+    The series used is:
+       ln(x) = 2(a+a^3/3+a^5/5+...) where a=(x-1)/(x+1)
+*/
+
+define l(x) {
+  auto b, e, f, i, m, n, v, z
+
+  /* Non base 10 ibase? */
+  if (ibase != A) {
+     b = ibase;
+     ibase = A;
+     v = l(x);
+     ibase = b;
+     return (v);
+  }
+
+  /* return something for the special case. */
+  if (x <= 0) return ((1 - 10^scale)/1)
+
+  /* Precondition x to make .5 < x < 2.0. */
+  z = scale;
+  scale = 6 + scale;
+  f = 2;
+  i=0
+  while (x >= 2) {  /* for large numbers */
+    f *= 2;
+    x = sqrt(x);
+  }
+  while (x <= .5) {  /* for small numbers */
+    f *= 2;
+    x = sqrt(x);
+  }
+
+  /* Set up the loop. */
+  v = n = (x-1)/(x+1)
+  m = n*n
+
+  /* Sum the series. */
+  for (i=3; 1; i+=2) {
+    e = (n *= m) / i
+    if (e == 0) {
+      v = f*v
+      scale = z
+      return (v/1)
+    }
+    v += e
+  }
+}
+
+/* Sin(x)  uses the standard series:
+   sin(x) = x - x^3/3! + x^5/5! - x^7/7! ... */
+
+define s(x) {
+  auto  b, e, i, m, n, s, v, z
+
+  /* Non base 10 ibase? */
+  if (ibase != A) {
+     b = ibase;
+     ibase = A;
+     v = s(x);
+     ibase = b;
+     return (v);
+  }
+
+  /* precondition x. */
+  z = scale 
+  scale = 1.1*z + 2;
+  v = a(1)
+  if (x < 0) {
+    m = 1;
+    x = -x;
+  }
+  scale = 0
+  n = (x / v + 2 )/4
+  x = x - 4*n*v
+  if (n%2) x = -x
+
+  /* Do the loop. */
+  scale = z + 2;
+  v = e = x
+  s = -x*x
+  for (i=3; 1; i+=2) {
+    e *= s/(i*(i-1))
+    if (e == 0) {
+      scale = z
+      if (m) return (-v/1);
+      return (v/1);
+    }
+    v += e
+  }
+}
+
+/* Cosine : cos(x) = sin(x+pi/2) */
+define c(x) {
+  auto b, v, z;
+
+  /* Non base 10 ibase? */
+  if (ibase != A) {
+     b = ibase;
+     ibase = A;
+     v = c(x);
+     ibase = b;
+     return (v);
+  }
+
+  z = scale;
+  scale = scale*1.2;
+  v = s(x+a(1)*2);
+  scale = z;
+  return (v/1);
+}
+
+/* Arctan: Using the formula:
+     atan(x) = atan(c) + atan((x-c)/(1+xc)) for a small c (.2 here)
+   For under .2, use the series:
+     atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ...   */
+
+define a(x) {
+  auto a, b, e, f, i, m, n, s, v, z
+
+  /* a is the value of a(.2) if it is needed. */
+  /* f is the value to multiply by a in the return. */
+  /* e is the value of the current term in the series. */
+  /* v is the accumulated value of the series. */
+  /* m is 1 or -1 depending on x (-x -> -1).  results are divided by m. */
+  /* i is the denominator value for series element. */
+  /* n is the numerator value for the series element. */
+  /* s is -x*x. */
+  /* z is the saved user's scale. */
+
+  /* Non base 10 ibase? */
+  if (ibase != A) {
+     b = ibase;
+     ibase = A;
+     v = a(x);
+     ibase = b;
+     return (v);
+  }
+
+  /* Negative x? */
+  m = 1;
+  if (x<0) {
+    m = -1;
+    x = -x;
+  }
+
+  /* Special case and for fast answers */
+  if (x==1) {
+    if (scale <= 25) return (.7853981633974483096156608/m)
+    if (scale <= 40) return (.7853981633974483096156608458198757210492/m)
+    if (scale <= 60) \
+      return (.785398163397448309615660845819875721049292349843776455243736/m)
+  }
+  if (x==.2) {
+    if (scale <= 25) return (.1973955598498807583700497/m)
+    if (scale <= 40) return (.1973955598498807583700497651947902934475/m)
+    if (scale <= 60) \
+      return (.197395559849880758370049765194790293447585103787852101517688/m)
+  }
+
+
+  /* Save the scale. */
+  z = scale;
+
+  /* Note: a and f are known to be zero due to being auto vars. */
+  /* Calculate atan of a known number. */ 
+  if (x > .2)  {
+    scale = z+5;
+    a = a(.2);
+  }
+   
+  /* Precondition x. */
+  scale = z+3;
+  while (x > .2) {
+    f += 1;
+    x = (x-.2) / (1+x*.2);
+  }
+
+  /* Initialize the series. */
+  v = n = x;
+  s = -x*x;
+
+  /* Calculate the series. */
+  for (i=3; 1; i+=2) {
+    e = (n *= s) / i;
+    if (e == 0) {
+      scale = z;
+      return ((f*a+v)/m);
+    }
+    v += e
+  }
+}
+
+
+/* Bessel function of integer order.  Uses the following:
+   j(-n,x) = (-1)^n*j(n,x) 
+   j(n,x) = x^n/(2^n*n!) * (1 - x^2/(2^2*1!*(n+1)) + x^4/(2^4*2!*(n+1)*(n+2))
+            - x^6/(2^6*3!*(n+1)*(n+2)*(n+3)) .... )
+*/
+define j(n,x) {
+  auto a, b, d, e, f, i, m, s, v, z
+
+  /* Non base 10 ibase? */
+  if (ibase != A) {
+     b = ibase;
+     ibase = A;
+     v = j(n,x);
+     ibase = b;
+     return (v);
+  }
+
+  /* Make n an integer and check for negative n. */
+  z = scale;
+  scale = 0;
+  n = n/1;
+  if (n<0) {
+    n = -n;
+    if (n%2 == 1) m = 1;
+  }
+
+  /* Compute the factor of x^n/(2^n*n!) */
+  f = 1;
+  for (i=2; i<=n; i++) f = f*i;
+  scale = 1.5*z;
+  f = x^n / 2^n / f;
+
+  /* Initialize the loop .*/
+  v = e = 1;
+  s = -x*x/4
+  scale = 1.5*z + length(f) - scale(f);
+
+  /* The Loop.... */
+  for (i=1; 1; i++) {
+    e =  e * s / i / (n+i);
+    if (e == 0) {
+       scale = z
+       if (m) return (-f*v/1);
+       return (f*v/1);
+    }
+    v += e;
+  }
+}
diff --git a/bc/libmath.h b/bc/libmath.h
new file mode 100644 (file)
index 0000000..63e1acb
--- /dev/null
@@ -0,0 +1,46 @@
+{"@iK20:s2:p@r",
+"@iF1,5.6,7,8,9,10,11,12,13,14,15[l0:KA:#Z1:l0:s7:pKA:s0:pl5:C1,0:",
+"s14:pl7:s0:pl14:RN1:l5:0<Z2:1s12:pl5:ns5:pN2:l2:s15:pK6:l15:+",
+"K.44:l5:*+s13:pl5:cS1+s2:pN3:l5:1>Z4:l10:1+s10:pl5:K2:/s5:pl2:",
+"1+s2:pJ3:N4:l13:s2:p1l5:+s14:pl5:s6:p1s8:pK2:s11:pN6:1B7:J5:N8:",
+"l11:i11:pJ6:N7:l6:l5:*s6:l8:l11:*s8:/s9:pl9:0=Z9:l10:0>Z10:N11:",
+"l10:d10:Z12:l14:l14:*s14:pJ11:N12:N10:l15:s2:pl12:Z13:1l14:/R",
+"N13:l14:1/RN9:l14:l9:+s14:pJ8:N5:0R]@r",
+"@iF2,5.7,9,10,11,12,13,14,15[l0:KA:#Z1:l0:s7:pKA:s0:pl5:C2,0:",
+"s14:pl7:s0:pl14:RN1:l5:0{Z2:1K10:l2:^-1/RN2:l2:s15:pK6:l2:+s2:",
+"pK2:s10:p0s11:pN3:l5:K2:}Z4:l10:K2:*s10:pl5:cRs5:pJ3:N4:N5:l5:",
+"K.5:{Z6:l10:K2:*s10:pl5:cRs5:pJ5:N6:l5:1-l5:1+/s13:s14:pl13:l13:",
+"*s12:pK3:s11:pN8:1B9:J7:N10:l11:K2:+s11:pJ8:N9:l13:l12:*s13:l11:",
+"/s9:pl9:0=Z11:l10:l14:*s14:pl15:s2:pl14:1/RN11:l14:l9:+s14:pJ10:N7:",
+"0R]@r",
+"@iF3,5.7,9,11,12,13,16,14,15[l0:KA:#Z1:l0:s7:pKA:s0:pl5:C3,0:",
+"s14:pl7:s0:pl14:RN1:l2:s15:pK1.1:l15:*K2:+s2:p1C4,0:s14:pl5:0",
+"<Z2:1s12:pl5:ns5:pN2:0s2:pl5:l14:/K2:+K4:/s13:pl5:K4:l13:*l14:",
+"*-s5:pl13:K2:%Z3:l5:ns5:pN3:l15:K2:+s2:pl5:s9:s14:pl5:nl5:*s16:",
+"pK3:s11:pN5:1B6:J4:N7:l11:K2:+s11:pJ5:N6:l9:l16:l11:l11:1-*/*",
+"s9:pl9:0=Z8:l15:s2:pl12:Z9:l14:n1/RN9:l14:1/RN8:l14:l9:+s14:p",
+"J7:N4:0R]@r",
+"@iF5,5.7,14,15[l0:KA:#Z1:l0:s7:pKA:s0:pl5:C5,0:s14:pl7:s0:pl14:",
+"RN1:l2:s15:pl2:K1.2:*s2:pl5:1C4,0:K2:*+C3,0:s14:pl15:s2:pl14:",
+"1/R0R]@r",
+"@iF4,5.6,7,9,10,11,12,13,16,14,15[l0:KA:#Z1:l0:s7:pKA:s0:pl5:",
+"C4,0:s14:pl7:s0:pl14:RN1:1s12:pl5:0<Z2:1ns12:pl5:ns5:pN2:l5:1",
+"=Z3:l2:K25:{Z4:K.7853981633974483096156608:l12:/RN4:l2:K40:{Z5:",
+"K.7853981633974483096156608458198757210492:l12:/RN5:l2:K60:{Z6:",
+"K.785398163397448309615660845819875721049292349843776455243736",
+":l12:/RN6:N3:l5:K.2:=Z7:l2:K25:{Z8:K.1973955598498807583700497",
+":l12:/RN8:l2:K40:{Z9:K.1973955598498807583700497651947902934475",
+":l12:/RN9:l2:K60:{Z10:K.197395559849880758370049765194790293447585103787852101517688",
+":l12:/RN10:N7:l2:s15:pl5:K.2:>Z11:l15:K5:+s2:pK.2:C4,0:s6:pN11:",
+"l15:K3:+s2:pN12:l5:K.2:>Z13:l10:1+s10:pl5:K.2:-1l5:K.2:*+/s5:",
+"pJ12:N13:l5:s13:s14:pl5:nl5:*s16:pK3:s11:pN15:1B16:J14:N17:l11:",
+"K2:+s11:pJ15:N16:l13:l16:*s13:l11:/s9:pl9:0=Z18:l15:s2:pl10:l6:",
+"*l14:+l12:/RN18:l14:l9:+s14:pJ17:N14:0R]@r",
+"@iF6,13,5.6,7,8,9,10,11,12,16,14,15[l0:KA:#Z1:l0:s7:pKA:s0:pl13:",
+"l5:C6,00:s14:pl7:s0:pl14:RN1:l2:s15:p0s2:pl13:1/s13:pl13:0<Z2:",
+"l13:ns13:pl13:K2:%1=Z3:1s12:pN3:N2:1s10:pK2:s11:pN5:l11:l13:{",
+"B6:J4:N7:l11:i11:pJ5:N6:l10:l11:*s10:pJ7:N4:K1.5:l15:*s2:pl5:",
+"l13:^K2:l13:^/l10:/s10:p1s9:s14:pl5:nl5:*K4:/s16:pK1.5:l15:*l10:",
+"cL+l10:cS-s2:p1s11:pN9:1B10:J8:N11:l11:i11:pJ9:N10:l9:l16:*l11:",
+"/l13:l11:+/s9:pl9:0=Z12:l15:s2:pl12:Z13:l10:nl14:*1/RN13:l10:",
+"l14:*1/RN12:l14:l9:+s14:pJ11:N8:0R]@r",0}
diff --git a/bc/load.c b/bc/load.c
new file mode 100644 (file)
index 0000000..1035198
--- /dev/null
+++ b/bc/load.c
@@ -0,0 +1,351 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* load.c:  This code "loads" code into the code segments. */
+
+#include "bcdefs.h"
+#include "proto.h"
+
+/* Load variables. */
+
+program_counter load_adr;
+char load_str;
+char load_const;
+
+/* Initialize the load sequence. */
+void
+init_load ()
+{
+  clear_func(0);
+  load_adr.pc_func = 0;
+  load_adr.pc_addr = 0;
+  load_str = FALSE;
+  load_const = FALSE;
+}
+
+/* addbyte adds one BYTE to the current code segment. */
+void
+addbyte (thebyte)
+     int thebyte;
+{
+  int prog_addr;
+  bc_function *f;
+  char *new_body;
+
+  /* If there was an error, don't continue. */
+  if (had_error) return;
+
+  /* Calculate the segment and offset. */
+  prog_addr = load_adr.pc_addr++;
+  f = &functions[load_adr.pc_func];
+
+  if (prog_addr >= f->f_body_size)
+    {
+      f->f_body_size *= 2;
+      new_body = (char *) bc_malloc (f->f_body_size);
+      memcpy(new_body, f->f_body, f->f_body_size/2);
+      free (f->f_body);
+      f->f_body = new_body;
+    }
+
+  /* Store the thebyte. */
+  f->f_body[prog_addr] = (char) (thebyte & 0xff);
+  f->f_code_size++;
+}
+
+
+/* Define a label LAB to be the current program counter. */
+
+void
+def_label (lab)
+     long lab;
+{
+  bc_label_group *temp;
+  int group, offset, func;
+    
+  /* Get things ready. */
+  group = lab >> BC_LABEL_LOG;
+  offset = lab % BC_LABEL_GROUP;
+  func = load_adr.pc_func;
+  
+  /* Make sure there is at least one label group. */
+  if (functions[func].f_label == NULL)
+    {
+      functions[func].f_label = 
+       (bc_label_group *) bc_malloc (sizeof(bc_label_group));
+      functions[func].f_label->l_next = NULL;
+    }
+
+  /* Add the label group. */
+  temp = functions[func].f_label;
+  while (group > 0)
+    {
+      if (temp->l_next == NULL)
+       {
+         temp->l_next = (bc_label_group *) bc_malloc (sizeof(bc_label_group));
+         temp->l_next->l_next = NULL;
+       }
+      temp = temp->l_next;
+      group --;
+    }
+
+  /* Define it! */
+  temp->l_adrs [offset] = load_adr.pc_addr;
+}
+
+/* Several instructions have integers in the code.  They
+   are all known to be legal longs.  So, no error code
+   is added.  STR is the pointer to the load string and
+   must be moved to the last non-digit character. */
+
+long
+long_val (str)
+     const char **str;
+{ int  val = 0;
+  char neg = FALSE;
+
+  if (**str == '-')
+    {
+      neg = TRUE;
+      (*str)++;
+    }
+  while (isdigit((int)(**str))) 
+    val = val*10 + *(*str)++ - '0';
+
+  if (neg)
+    return -val;
+  else
+    return val;
+}
+
+
+/* load_code loads the CODE into the machine. */
+
+void
+load_code (code)
+     const char *code;
+{
+  const char *str;
+  long  ap_name;       /* auto or parameter name. */
+  long  label_no;
+  long  vaf_name;      /* variable, array or function number. */
+  long  func;
+  static program_counter save_adr;
+
+  /* Initialize. */
+  str = code;
+   
+  /* Scan the code. */
+  while (*str != 0)
+    {
+      /* If there was an error, don't continue. */
+      if (had_error) return;
+
+      if (load_str)
+       {
+         if (*str == '"') load_str = FALSE;
+         addbyte (*str++);
+       }
+      else
+       if (load_const)
+         {
+           if (*str == '\n') 
+             str++;
+           else
+             {
+               if (*str == ':')
+                 {
+                   load_const = FALSE;
+                   addbyte (*str++);
+                 }
+               else
+                 if (*str == '.')
+                   addbyte (*str++);
+                 else
+                   if (*str >= 'A')
+                     addbyte (*str++ + 10 - 'A');
+                   else
+                     addbyte (*str++ - '0');
+             }
+         }
+       else
+         {
+           switch (*str)
+             {
+
+             case '"': /* Starts a string. */
+               load_str = TRUE;
+               break;
+
+             case 'N': /* A label */
+               str++;
+               label_no = long_val (&str);
+               def_label (label_no);
+               break;
+
+             case 'B':  /* Branch to label. */
+             case 'J':  /* Jump to label. */
+             case 'Z':  /* Branch Zero to label. */
+               addbyte(*str++);
+               label_no = long_val (&str);
+               if (label_no > 65535L)
+                 {  /* Better message? */
+                   fprintf (stderr,"Program too big.\n");
+                   exit(1);
+                 }
+               addbyte ( (char) (label_no & 0xFF));
+               addbyte ( (char) (label_no >> 8));
+               break;
+
+             case 'F':  /* A function, get the name and initialize it. */
+               str++;
+               func = long_val (&str);
+               clear_func (func);
+#if DEBUG > 2
+               printf ("Loading function number %d\n", func);
+#endif
+               /* get the parameters */
+               while (*str++ != '.')
+                 {
+                   if (*str == '.')
+                     {
+                       str++;
+                       break;
+                     }
+                   if (*str == '*')
+                     {
+                       str++;
+                       ap_name = long_val (&str);
+#if DEBUG > 2
+                       printf ("var parameter number %d\n", ap_name);
+#endif
+                       functions[(int)func].f_params = 
+                         nextarg (functions[(int)func].f_params, ap_name,
+                                  TRUE);
+                     }
+                   else
+                     {
+                       ap_name = long_val (&str);
+#if DEBUG > 2
+                       printf ("parameter number %d\n", ap_name);
+#endif
+                       functions[(int)func].f_params = 
+                         nextarg (functions[(int)func].f_params, ap_name,
+                                  FALSE);
+                     }
+                 }
+
+               /* get the auto vars */
+               while (*str != '[')
+                 {
+                   if (*str == ',') str++;
+                   ap_name = long_val (&str);
+#if DEBUG > 2
+                   printf ("auto number %d\n", ap_name);
+#endif
+                   functions[(int)func].f_autos = 
+                     nextarg (functions[(int)func].f_autos, ap_name, FALSE);
+                 }
+               save_adr = load_adr;
+               load_adr.pc_func = func;
+               load_adr.pc_addr = 0;
+               break;
+               
+             case ']':  /* A function end */
+               functions[load_adr.pc_func].f_defined = TRUE;
+               load_adr = save_adr;
+               break;
+
+             case 'C':  /* Call a function. */
+               addbyte (*str++);
+               func = long_val (&str);
+               if (func < 128)
+                 addbyte ( (char) func);
+               else
+                 {
+                   addbyte (((func >> 8) & 0xff) | 0x80);
+                   addbyte (func & 0xff);
+                 }
+               if (*str == ',') str++;
+               while (*str != ':')
+                 addbyte (*str++);
+               addbyte (':');
+               break;
+               
+             case 'c':  /* Call a special function. */
+               addbyte (*str++);
+               addbyte (*str);
+               break;
+
+             case 'K':  /* A constant.... may have an "F" in it. */
+               addbyte (*str);
+               load_const = TRUE;
+               break;
+
+             case 'd':  /* Decrement. */
+             case 'i':  /* Increment. */
+             case 'l':  /* Load. */
+             case 's':  /* Store. */
+             case 'A':  /* Array Increment */
+             case 'M':  /* Array Decrement */
+             case 'L':  /* Array Load */
+             case 'S':  /* Array Store */
+               addbyte (*str++);
+               vaf_name = long_val (&str);
+               if (vaf_name < 128)
+                 addbyte (vaf_name);
+               else
+                 {
+                   addbyte (((vaf_name >> 8) & 0xff) | 0x80);
+                   addbyte (vaf_name & 0xff);
+                 }
+               break;
+
+             case '@':  /* A command! */
+               switch (*(++str))
+                 {
+                 case 'i':
+                   init_load ();
+                   break;
+                 case 'r':
+                   execute ();
+                   break;
+                 } 
+               break;
+
+             case '\n':  /* Ignore the newlines */
+               break;
+               
+             default:   /* Anything else */
+               addbyte (*str);    
+             }
+           str++;
+         }
+    }
+}
diff --git a/bc/main.c b/bc/main.c
new file mode 100644 (file)
index 0000000..9a2461e
--- /dev/null
+++ b/bc/main.c
@@ -0,0 +1,367 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* main.c: The main program for bc.  */
+
+#include "bcdefs.h"
+#include <signal.h>
+#include <errno.h>
+#include "proto.h"
+#include "getopt.h"
+
+
+/* Variables for processing multiple files. */
+static char first_file;
+
+/* Points to the last node in the file name list for easy adding. */
+static file_node *last = NULL;
+
+/* long option support */
+static struct option long_options[] =
+{
+  {"compile",     0, &compile_only, TRUE},
+  {"help",        0, 0,             'h'},
+  {"interactive", 0, 0,             'i'},
+  {"mathlib",     0, &use_math,     TRUE},
+  {"quiet",       0, &quiet,        TRUE},
+  {"standard",    0, &std_only,     TRUE},
+  {"version",     0, 0,             'v'},
+  {"warn",        0, &warn_not_std, TRUE},
+
+  {0, 0, 0, 0}
+};
+
+
+static void
+usage (const char *progname)
+{
+  printf ("usage: %s [options] [file ...]\n%s%s%s%s%s%s%s", progname,
+          "  -h  --help         print this usage and exit\n",
+         "  -i  --interactive  force interactive mode\n",
+         "  -l  --mathlib      use the predefined math routines\n",
+         "  -q  --quiet        don't print initial banner\n",
+         "  -s  --standard     non-standard bc constructs are errors\n",
+         "  -w  --warn         warn about non-standard bc constructs\n",
+         "  -v  --version      print version information and exit\n");
+}
+
+
+static void
+parse_args (argc, argv)
+     int argc;
+     char **argv;
+{
+  int optch;
+  int long_index;
+  file_node *temp;
+
+  /* Force getopt to initialize.  Depends on GNU getopt. */
+  optind = 0;
+
+  /* Parse the command line */
+  while (1)
+    {
+      optch = getopt_long (argc, argv, "chilqswv", long_options, &long_index);
+
+      if (optch == EOF)  /* End of arguments. */
+       break;
+
+      switch (optch)
+       {
+       case 0: /* Long option setting a var. */
+         break;
+
+       case 'c':  /* compile only */
+         compile_only = TRUE;
+         break;
+
+       case 'h':  /* help */
+         usage(argv[0]);
+         exit (0);
+         break;
+
+       case 'i':  /* force interactive */
+         interactive = TRUE;
+         break;
+
+       case 'l':  /* math lib */
+         use_math = TRUE;
+         break;
+
+       case 'q':  /* quiet mode */
+         quiet = TRUE;
+         break;
+
+       case 's':  /* Non standard features give errors. */
+         std_only = TRUE;
+         break;
+
+       case 'v':  /* Print the version. */
+         show_bc_version ();
+         exit (0);
+         break;
+
+       case 'w':  /* Non standard features give warnings. */
+         warn_not_std = TRUE;
+         break;
+
+       default:
+         usage(argv[0]);
+         exit (1);
+       }
+    }
+
+#ifdef QUIET
+  quiet = TRUE;
+#endif
+
+  /* Add file names to a list of files to process. */
+  while (optind < argc)
+    {
+      temp = (file_node *) bc_malloc(sizeof(file_node));
+      temp->name = argv[optind];
+      temp->next = NULL;
+      if (last == NULL)
+       file_names = temp;
+      else
+       last->next = temp;
+      last = temp;
+      optind++;
+    }
+}
+
+/* The main program for bc. */
+int
+main (argc, argv)
+     int argc;
+     char *argv[];
+{
+  char *env_value;
+  const char *env_argv[30];
+  int   env_argc;
+  
+  /* Interactive? */
+  if (isatty(0) && isatty(1)) 
+    interactive = TRUE;
+
+#ifdef HAVE_SETVBUF
+  /* attempt to simplify interaction with applications such as emacs */
+  (void) setvbuf(stdout, NULL, _IOLBF, 0);
+#endif
+
+  /* Environment arguments. */
+  env_value = getenv ("BC_ENV_ARGS");
+  if (env_value != NULL)
+    {
+      env_argc = 1;
+      env_argv[0] = "BC_ENV_ARGS";
+      while (*env_value != 0)
+       {
+         if (*env_value != ' ')
+           {
+             env_argv[env_argc++] = env_value;
+             while (*env_value != ' ' && *env_value != 0)
+               env_value++;
+             if (*env_value != 0)
+               {
+                 *env_value = 0;
+                 env_value++;
+               }
+           }
+         else
+           env_value++;
+       }
+      parse_args (env_argc, env_argv);
+    }
+
+  /* Command line arguments. */
+  parse_args (argc, argv);
+
+  /* Other environment processing. */
+  if (getenv ("POSIXLY_CORRECT") != NULL)
+    std_only = TRUE;
+
+  env_value = getenv ("BC_LINE_LENGTH");
+  if (env_value != NULL)
+    {
+      line_size = atoi (env_value);
+      if (line_size < 3 && line_size != 0)
+       line_size = 70;
+    }
+  else
+    line_size = 70;
+
+  /* Initialize the machine.  */
+  init_storage();
+  init_load();
+
+  /* Set up interrupts to print a message. */
+  if (interactive)
+    signal (SIGINT, use_quit);
+
+  /* Initialize the front end. */
+  init_tree();
+  init_gen ();
+  is_std_in = FALSE;
+  first_file = TRUE;
+  if (!open_new_file ())
+    exit (1);
+
+#if defined(LIBEDIT)
+  if (interactive) {
+    /* Enable libedit support. */
+    edit = el_init ("bc", stdin, stdout, stderr);
+    hist = history_init();
+    el_set (edit, EL_EDITOR, "emacs");
+    el_set (edit, EL_HIST, history, hist);
+    el_set (edit, EL_PROMPT, null_prompt);
+    el_source (edit, NULL);
+    history (hist, &histev, H_SETSIZE, INT_MAX);
+  }
+#endif
+
+#if defined(READLINE)
+  if (interactive) {
+    /* Readline support.  Set both application name and input file. */
+    rl_readline_name = "bc";
+    rl_instream = stdin;
+    using_history ();
+  }
+#endif
+
+  /* Do the parse. */
+  yyparse ();
+
+  /* End the compile only output with a newline. */
+  if (compile_only)
+    printf ("\n");
+
+#if defined(LIBEDIT)
+  if (edit != NULL)
+    el_end(edit);
+#endif
+  exit (0);
+}
+
+
+/* This is the function that opens all the files. 
+   It returns TRUE if the file was opened, otherwise
+   it returns FALSE. */
+
+int
+open_new_file ()
+{
+  FILE *new_file;
+  file_node *temp;
+
+  /* Set the line number. */
+  line_no = 1;
+
+  /* Check to see if we are done. */
+  if (is_std_in) return (FALSE);
+
+  /* Open the other files. */
+  if (use_math && first_file)
+    {
+      /* Load the code from a precompiled version of the math libarary. */
+      extern char *libmath[];
+      char **mstr;
+      char tmp;
+      /* These MUST be in the order of first mention of each function.
+        That is why "a" comes before "c" even though "a" is defined after
+        after "c".  "a" is used in "s"! */
+      tmp = lookup ("e", FUNCT);
+      tmp = lookup ("l", FUNCT);
+      tmp = lookup ("s", FUNCT);
+      tmp = lookup ("a", FUNCT);
+      tmp = lookup ("c", FUNCT);
+      tmp = lookup ("j", FUNCT);
+      mstr = libmath;
+      while (*mstr) {
+           load_code (*mstr);
+          mstr++;
+      }
+    }
+  
+  /* One of the argv values. */
+  if (file_names != NULL)
+    {
+      new_file = fopen (file_names->name, "r");
+      if (new_file != NULL)
+       {
+         new_yy_file (new_file);
+         temp = file_names;
+         file_name  = temp->name;
+         file_names = temp->next;
+         free (temp);
+         return TRUE;
+       }
+      fprintf (stderr, "File %s is unavailable.\n", file_names->name);
+      exit (1);
+    }
+  
+  /* If we fall through to here, we should return stdin. */
+  new_yy_file (stdin);
+  is_std_in = TRUE;
+  return TRUE;
+}
+
+
+/* Set yyin to the new file. */
+
+void
+new_yy_file (file)
+     FILE *file;
+{
+  if (!first_file) fclose (yyin);
+  yyin = file;
+  first_file = FALSE;
+}
+
+
+/* Message to use quit.  */
+
+void
+use_quit (sig)
+     int sig;
+{
+#ifdef DONTEXIT
+  int save = errno;
+  write (1, "\n(interrupt) use quit to exit.\n", 31);
+  signal (SIGINT, use_quit);
+  errno = save;
+#else
+  write (1, "\n(interrupt) Exiting bc.\n", 26);
+#if defined(LIBEDIT)
+  if (edit != NULL)
+    el_end(edit);
+#endif
+  exit(0);
+#endif
+}
diff --git a/bc/proto.h b/bc/proto.h
new file mode 100644 (file)
index 0000000..6d1b08b
--- /dev/null
@@ -0,0 +1,150 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* proto.h: Prototype function definitions for "external" functions. */
+
+/* For the pc version using k&r ACK. (minix1.5 and earlier.) */
+#ifdef SHORTNAMES
+#define init_numbers i_numbers
+#define push_constant push__constant
+#define load_const in_load_const
+#define yy_get_next_buffer yyget_next_buffer
+#define yy_init_buffer yyinit_buffer
+#define yy_last_accepting_state yylast_accepting_state
+#define arglist1 arg1list
+#endif
+
+/* Include the standard library header files. */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+/* Define the _PROTOTYPE macro if it is needed. */
+
+#ifndef _PROTOTYPE
+#ifdef __STDC__
+#define _PROTOTYPE(func, args) func args
+#else
+#define _PROTOTYPE(func, args) func()
+#endif
+#endif
+
+/* From execute.c */
+_PROTOTYPE(void stop_execution, (int));
+_PROTOTYPE(unsigned char byte, (program_counter *pc_));
+_PROTOTYPE(void execute, (void));
+_PROTOTYPE(int prog_char, (void));
+_PROTOTYPE(int input_char, (void));
+_PROTOTYPE(void push_constant, (int (*in_char)(void), int conv_base));
+_PROTOTYPE(void push_b10_const, (program_counter *pc_));
+_PROTOTYPE(void assign, (int c_code_));
+
+/* From util.c */
+_PROTOTYPE(char *strcopyof, (const char *str));
+_PROTOTYPE(arg_list *nextarg, (arg_list *args, int val, int is_var));
+_PROTOTYPE(char *arg_str, (arg_list *args));
+_PROTOTYPE(char *call_str, (arg_list *args));
+_PROTOTYPE(void free_args, (arg_list *args));
+_PROTOTYPE(void check_params, (arg_list *params, arg_list *autos));
+_PROTOTYPE(void set_genstr_size, (int));
+_PROTOTYPE(void init_gen, (void));
+_PROTOTYPE(void generate, (const char *str));
+_PROTOTYPE(void run_code, (void));
+_PROTOTYPE(void out_char, (int ch));
+_PROTOTYPE(void out_schar, (int ch));
+_PROTOTYPE(id_rec *find_id, (id_rec *tree, const char *id));
+_PROTOTYPE(int insert_id_rec, (id_rec **root, id_rec *new_id));
+_PROTOTYPE(void init_tree, (void));
+_PROTOTYPE(int lookup, (char *name, int namekind));
+_PROTOTYPE(void *bc_malloc, (int));
+_PROTOTYPE(void out_of_memory, (void));
+_PROTOTYPE(void welcome, (void));
+_PROTOTYPE(void warranty, (const char *));
+_PROTOTYPE(void show_bc_version, (void));
+_PROTOTYPE(void limits, (void));
+_PROTOTYPE(void yyerror, (const char *str ,...));
+_PROTOTYPE(void warn, (const char *mesg ,...));
+_PROTOTYPE(void rt_error, (const char *mesg ,...));
+_PROTOTYPE(void rt_warn, (const char *mesg ,...));
+
+/* From load.c */
+_PROTOTYPE(void init_load, (void));
+_PROTOTYPE(void addbyte, (int byte_));
+_PROTOTYPE(void def_label, (long lab));
+_PROTOTYPE(long long_val, (const char **str));
+_PROTOTYPE(void load_code, (const char *code));
+
+/* From main.c */
+_PROTOTYPE(int open_new_file, (void));
+_PROTOTYPE(void new_yy_file, (FILE *file));
+_PROTOTYPE(void use_quit, (int));
+
+/* From storage.c */
+_PROTOTYPE(void init_storage, (void));
+_PROTOTYPE(void more_functions, (void));
+_PROTOTYPE(void more_variables, (void));
+_PROTOTYPE(void more_arrays, (void));
+_PROTOTYPE(void clear_func, (int func ));
+_PROTOTYPE(int fpop, (void));
+_PROTOTYPE(void fpush, (int val ));
+_PROTOTYPE(void pop, (void));
+_PROTOTYPE(void push_copy, (bc_num num ));
+_PROTOTYPE(void push_num, (bc_num num ));
+_PROTOTYPE(char check_stack, (int depth ));
+_PROTOTYPE(bc_var *get_var, (int var_name ));
+_PROTOTYPE(bc_num *get_array_num, (int var_index, long _index_ ));
+_PROTOTYPE(void store_var, (int var_name ));
+_PROTOTYPE(void store_array, (int var_name ));
+_PROTOTYPE(void load_var, (int var_name ));
+_PROTOTYPE(void load_array, (int var_name ));
+_PROTOTYPE(void decr_var, (int var_name ));
+_PROTOTYPE(void decr_array, (int var_name ));
+_PROTOTYPE(void incr_var, (int var_name ));
+_PROTOTYPE(void incr_array, (int var_name ));
+_PROTOTYPE(void auto_var, (int name ));
+_PROTOTYPE(void free_a_tree, (bc_array_node *root, int depth ));
+_PROTOTYPE(void pop_vars, (arg_list *list ));
+_PROTOTYPE(void process_params, (program_counter *_pc_, int func ));
+
+/* For the scanner and parser.... */
+_PROTOTYPE(int yyparse, (void));
+_PROTOTYPE(int yylex, (void)); 
+
+#if defined(LIBEDIT)
+/* The *?*&^ prompt function */
+_PROTOTYPE(char *null_prompt, (EditLine *));
+#endif
+
+/* Other things... */
+#ifndef HAVE_UNISTD_H
+_PROTOTYPE (int getopt, (int, char *[], CONST char *));
+#endif
diff --git a/bc/sbc.y b/bc/sbc.y
new file mode 100644 (file)
index 0000000..0ded29e
--- /dev/null
+++ b/bc/sbc.y
@@ -0,0 +1,454 @@
+%{
+/* sbc.y: A POSIX bc processor written for minix with no extensions.  */
+/*  This file is part of GNU bc.
+    Copyright (C) 1991, 1992, 1993, 1994, 1997 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to
+      The Free Software Foundation, Inc.
+      51 Franklin Street, Fifth Floor
+      Boston, MA 02110-1301  USA
+
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+#include "bcdefs.h"
+#include "global.h"     /* To get the global variables. */
+#include "proto.h"
+%}
+
+%start program
+
+%union {
+       char *s_value;
+       char  c_value;
+       int   i_value;
+       arg_list *a_value;
+       }
+
+%token <i_value> ENDOFLINE AND OR NOT
+%token <s_value> STRING NAME NUMBER
+/*     '-', '+' are tokens themselves          */
+%token <c_value> ASSIGN_OP
+/*     '=', '+=',  '-=', '*=', '/=', '%=', '^=' */
+%token <s_value> REL_OP
+/*     '==', '<=', '>=', '!=', '<', '>'        */
+%token <c_value> INCR_DECR
+/*     '++', '--'                              */
+%token <i_value> Define    Break    Quit    Length
+/*     'define', 'break', 'quit', 'length'     */
+%token <i_value> Return    For    If    While    Sqrt  Else
+/*     'return', 'for', 'if', 'while', 'sqrt',  'else'         */
+%token <i_value> Scale    Ibase    Obase    Auto  Read
+/*     'scale', 'ibase', 'obase', 'auto', 'read'       */
+%token <i_value> Warranty, Halt, Last, Continue, Print, Limits
+/*     'warranty', 'halt', 'last', 'continue', 'print', 'limits'  */
+
+/* The types of all other non-terminals. */
+%type <i_value> expression named_expression return_expression
+%type <a_value> opt_parameter_list parameter_list opt_auto_define_list
+%type <a_value> define_list opt_argument_list argument_list
+%type <i_value> program input_item semicolon_list statement_list
+%type <i_value> statement_or_error statement function relational_expression 
+
+/* precedence */
+%nonassoc REL_OP
+%right ASSIGN_OP
+%left '+' '-'
+%left '*' '/' '%'
+%right '^'
+%nonassoc UNARY_MINUS
+%nonassoc INCR_DECR
+
+%%
+program                        : /* empty */
+                           {
+                             $$ = 0;
+                             std_only = TRUE;
+                             if (interactive && !quiet)
+                               {
+                                 show_bc_version ();
+                                 welcome ();
+                               }
+                           }
+                       | program input_item
+                       ;
+input_item             : semicolon_list ENDOFLINE
+                           { run_code (); }
+                       | function
+                           { run_code (); }
+                       | error ENDOFLINE
+                           {
+                             yyerrok; 
+                             init_gen () ;
+                           }
+                       ;
+semicolon_list         : /* empty */
+                           { $$ = 0; }
+                       | statement_or_error
+                       | semicolon_list ';' statement_or_error
+                       | semicolon_list ';'
+                       ;
+statement_list         : /* empty */
+                           { $$ = 0; }
+                       | statement
+                       | statement_list ENDOFLINE
+                       | statement_list ENDOFLINE statement
+                       | statement_list ';'
+                       | statement_list ';' statement
+                       ;
+statement_or_error     : statement
+                       | error statement
+                           { $$ = $2; }
+                       ;
+statement              : Warranty
+                           { warranty ("s"); }
+                       | expression
+                           {
+                             if ($1 & 1)
+                               generate ("W");
+                             else
+                               generate ("p");
+                           }
+                       | STRING
+                           {
+                             $$ = 0;
+                             generate ("w");
+                             generate ($1);
+                             free ($1);
+                           }
+                       | Break
+                           {
+                             if (break_label == 0)
+                               yyerror ("Break outside a for/while");
+                             else
+                               {
+                                 sprintf (genstr, "J%1d:", break_label);
+                                 generate (genstr);
+                               }
+                           }
+                       | Quit
+                           { exit (0); }
+                       | Return
+                           { generate ("0R"); }
+                       | Return '(' return_expression ')'
+                           { generate ("R"); }
+                       | For 
+                           {
+                             $1 = break_label; 
+                             break_label = next_label++;
+                           }
+                         '(' expression ';'
+                           {
+                             $4 = next_label++;
+                             sprintf (genstr, "pN%1d:", $4);
+                             generate (genstr);
+                           }
+                         relational_expression ';'
+                           {
+                             $7 = next_label++;
+                             sprintf (genstr, "B%1d:J%1d:", $7, break_label);
+                             generate (genstr);
+                             $<i_value>$ = next_label++;
+                             sprintf (genstr, "N%1d:", $<i_value>$);
+                             generate (genstr);
+                           }
+                         expression ')'
+                           {
+                             sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
+                             generate (genstr);
+                           }
+                         statement
+                           {
+                             sprintf (genstr, "J%1d:N%1d:", $<i_value>9,
+                                      break_label);
+                             generate (genstr);
+                             break_label = $1;
+                           }
+                       | If '(' relational_expression ')' 
+                           {
+                             $3 = next_label++;
+                             sprintf (genstr, "Z%1d:", $3);
+                             generate (genstr);
+                           }
+                         statement
+                           {
+                             sprintf (genstr, "N%1d:", $3); 
+                             generate (genstr);
+                           }
+                       | While 
+                           {
+                             $1 = next_label++;
+                             sprintf (genstr, "N%1d:", $1);
+                             generate (genstr);
+                           }
+                       '(' relational_expression 
+                           {
+                             $4 = break_label; 
+                             break_label = next_label++;
+                             sprintf (genstr, "Z%1d:", break_label);
+                             generate (genstr);
+                           }
+                       ')' statement
+                           {
+                             sprintf (genstr, "J%1d:N%1d:", $1, break_label);
+                             generate (genstr);
+                             break_label = $4;
+                           }
+                       | '{' statement_list '}'
+                           { $$ = 0; }
+                       ;
+function               : Define NAME '(' opt_parameter_list ')' '{'
+                                 ENDOFLINE opt_auto_define_list 
+                           { char *params, *autos;
+                             check_params ($4,$8);
+                             params = arg_str ($4);
+                             autos = arg_str ($8);
+                             set_genstr_size (30 + strlen (params)
+                                              + strlen (autos));
+                             sprintf (genstr, "F%d,%s.%s[", lookup ($2,FUNCT),
+                                      params, autos);
+                             generate (genstr);
+                             free_args ($4);
+                             free_args ($8);
+                             $1 = next_label;
+                             next_label = 0;
+                           }
+                         statement_list ENDOFLINE '}'
+                           {
+                             generate ("0R]");
+                             next_label = $1;
+                           }
+                       ;
+opt_parameter_list     : /* empty */ 
+                           { $$ = NULL; }
+                       | parameter_list
+                       ;
+parameter_list                 : NAME
+                           { $$ = nextarg (NULL, lookup ($1,SIMPLE), FALSE); }
+                       | define_list ',' NAME
+                           { $$ = nextarg ($1, lookup ($3,SIMPLE), FALSE); }
+                       ;
+opt_auto_define_list   : /* empty */ 
+                           { $$ = NULL; }
+                       | Auto define_list ENDOFLINE
+                           { $$ = $2; } 
+                       | Auto define_list ';'
+                           { $$ = $2; } 
+                       ;
+define_list            : NAME
+                           { $$ = nextarg (NULL, lookup ($1,SIMPLE), FALSE); }
+                       | NAME '[' ']'
+                           { $$ = nextarg (NULL, lookup ($1,ARRAY), FALSE); }
+                       | define_list ',' NAME
+                           { $$ = nextarg ($1, lookup ($3,SIMPLE), FALSE); }
+                       | define_list ',' NAME '[' ']'
+                           { $$ = nextarg ($1, lookup ($3,ARRAY), FALSE); }
+                       ;
+opt_argument_list      : /* empty */
+                           { $$ = NULL; }
+                       | argument_list
+                       ;
+argument_list          : expression
+                           { $$ = nextarg (NULL,0, FALSE); }
+                       | argument_list ',' expression
+                           { $$ = nextarg ($1,0, FALSE); }
+                       ;
+relational_expression  : expression
+                           { $$ = 0; }
+                       | expression REL_OP expression
+                           {
+                             $$ = 0;
+                             switch (*($2))
+                               {
+                               case '=':
+                                 generate ("=");
+                                 break;
+                               case '!':
+                                 generate ("#");
+                                 break;
+                               case '<':
+                                 if ($2[1] == '=')
+                                   generate ("{");
+                                 else
+                                   generate ("<");
+                                 break;
+                               case '>':
+                                 if ($2[1] == '=')
+                                   generate ("}");
+                                 else
+                                   generate (">");
+                                 break;
+                               }
+                           }
+                       ;
+return_expression      : /* empty */
+                           {
+                             $$ = 0;
+                             generate ("0");
+                           }
+                       | expression
+                       ;
+expression             : named_expression ASSIGN_OP 
+                           {
+                             if ($2 != '=')
+                               {
+                                 if ($1 < 0)
+                                   sprintf (genstr, "DL%d:", -$1);
+                                 else
+                                   sprintf (genstr, "l%d:", $1);
+                                 generate (genstr);
+                               }
+                           }
+                         expression
+                           {
+                             $$ = 0;
+                             if ($2 != '=')
+                               {
+                                 sprintf (genstr, "%c", $2);
+                                 generate (genstr);
+                               }
+                             if ($1 < 0)
+                               sprintf (genstr, "S%d:", -$1);
+                             else
+                               sprintf (genstr, "s%d:", $1);
+                             generate (genstr);
+                           }
+                       | expression '+' expression
+                           { generate ("+"); }
+                       | expression '-' expression
+                           { generate ("-"); }
+                       | expression '*' expression
+                           { generate ("*"); }
+                       | expression '/' expression
+                           { generate ("/"); }
+                       | expression '%' expression
+                           { generate ("%"); }
+                       | expression '^' expression
+                           { generate ("^"); }
+                       | '-' expression           %prec UNARY_MINUS
+                           { generate ("n"); $$ = 1;}
+                       | named_expression
+                           {
+                             $$ = 1;
+                             if ($1 < 0)
+                               sprintf (genstr, "L%d:", -$1);
+                             else
+                               sprintf (genstr, "l%d:", $1);
+                             generate (genstr);
+                           }
+                       | NUMBER
+                           {
+                             int len = strlen ($1);
+                             $$ = 1;
+                             if (len == 1 && *$1 == '0')
+                               generate ("0");
+                             else
+                               {
+                                 if (len == 1 && *$1 == '1')
+                                   generate ("1");
+                                 else
+                                   {
+                                     generate ("K");
+                                     generate ($1);
+                                     generate (":");
+                                   }
+                                 free ($1);
+                               }
+                           }
+                       | '(' expression ')'
+                           { $$ = 1; }
+                       | NAME '(' opt_argument_list ')'
+                           {
+                             $$ = 1;
+                             if ($3 != NULL)
+                               { char *params = call_str ($3);
+                                 set_genstr_size (20 + strlen (params));
+                                 sprintf (genstr, "C%d,%s:",
+                                          lookup ($1,FUNCT), params);
+                                 free_args ($3);
+                               }
+                             else
+                                 sprintf (genstr, "C%d:", lookup ($1,FUNCT));
+                             generate (genstr);
+                           }
+                       | INCR_DECR named_expression
+                           {
+                             $$ = 1;
+                             if ($2 < 0)
+                               {
+                                 if ($1 == '+')
+                                   sprintf (genstr, "DA%d:L%d:", -$2, -$2);
+                                 else
+                                   sprintf (genstr, "DM%d:L%d:", -$2, -$2);
+                               }
+                             else
+                               {
+                                 if ($1 == '+')
+                                   sprintf (genstr, "i%d:l%d:", $2, $2);
+                                 else
+                                   sprintf (genstr, "d%d:l%d:", $2, $2);
+                               }
+                             generate (genstr);
+                           }
+                       | named_expression INCR_DECR
+                           {
+                             $$ = 1;
+                             if ($1 < 0)
+                               {
+                                 sprintf (genstr, "DL%d:x", -$1);
+                                 generate (genstr); 
+                                 if ($2 == '+')
+                                   sprintf (genstr, "A%d:", -$1);
+                                 else
+                                   sprintf (genstr, "M%d:", -$1);
+                               }
+                             else
+                               {
+                                 sprintf (genstr, "l%d:", $1);
+                                 generate (genstr);
+                                 if ($2 == '+')
+                                   sprintf (genstr, "i%d:", $1);
+                                 else
+                                   sprintf (genstr, "d%d:", $1);
+                               }
+                             generate (genstr);
+                           }
+                       | Length '(' expression ')'
+                           { generate ("cL"); $$ = 1;}
+                       | Sqrt '(' expression ')'
+                           { generate ("cR"); $$ = 1;}
+                       | Scale '(' expression ')'
+                           { generate ("cS"); $$ = 1;}
+                       ;
+named_expression       : NAME
+                           { $$ = lookup ($1,SIMPLE); }
+                       | NAME '[' expression ']'
+                           { $$ = lookup ($1,ARRAY); }
+                       | Ibase
+                           { $$ = 0; }
+                       | Obase
+                           { $$ = 1; }
+                       | Scale
+                           { $$ = 2; }
+                       ;
+
+%%
diff --git a/bc/scan.c b/bc/scan.c
new file mode 100644 (file)
index 0000000..1f78ec2
--- /dev/null
+++ b/bc/scan.c
@@ -0,0 +1,2489 @@
+
+#line 3 "scan.c"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else  /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               *yy_cp = (yy_hold_char); \
+               YY_RESTORE_YY_MORE_OFFSET \
+               (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+               } \
+       while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+       {
+       FILE *yy_input_file;
+
+       char *yy_ch_buf;                /* input buffer */
+       char *yy_buf_pos;               /* current position in input buffer */
+
+       /* Size of input buffer in bytes, not including room for EOB
+        * characters.
+        */
+       yy_size_t yy_buf_size;
+
+       /* Number of characters read into yy_ch_buf, not including EOB
+        * characters.
+        */
+       int yy_n_chars;
+
+       /* Whether we "own" the buffer - i.e., we know we created it,
+        * and can realloc() it to grow it, and should free() it to
+        * delete it.
+        */
+       int yy_is_our_buffer;
+
+       /* Whether this is an "interactive" input source; if so, and
+        * if we're using stdio for input, then we want to use getc()
+        * instead of fread(), to make sure we stop fetching input after
+        * each newline.
+        */
+       int yy_is_interactive;
+
+       /* Whether we're considered to be at the beginning of a line.
+        * If so, '^' rules will be active on the next match, otherwise
+        * not.
+        */
+       int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+       /* Whether to try to fill the input buffer when we reach the
+        * end of it.
+        */
+       int yy_fill_buffer;
+
+       int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+       /* When an EOF's been seen but there's still some text to process
+        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+        * shouldn't try reading from the input source any more.  We might
+        * still have a bunch of tokens to match, though, because of
+        * possible backing-up.
+        *
+        * When we actually see the EOF, we change the status to "new"
+        * (via yyrestart()), so that the user can continue scanning by
+        * just pointing yyin at a new input file.
+        */
+#define YY_BUFFER_EOF_PENDING 2
+
+       };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;         /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;                /* whether we need to initialize */
+static int yy_start = 0;       /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file  );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
+void yy_delete_buffer (YY_BUFFER_STATE b  );
+void yy_flush_buffer (YY_BUFFER_STATE b  );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+
+void *yyalloc (yy_size_t  );
+void *yyrealloc (void *,yy_size_t  );
+void yyfree (void *  );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+       }
+
+#define yy_set_bol(at_bol) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+       }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+       (yytext_ptr) = yy_bp; \
+       yyleng = (size_t) (yy_cp - yy_bp); \
+       (yy_hold_char) = *yy_cp; \
+       *yy_cp = '\0'; \
+       (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 46
+#define YY_END_OF_BUFFER 47
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+       {
+       flex_int32_t yy_verify;
+       flex_int32_t yy_nxt;
+       };
+static yyconst flex_int16_t yy_accept[316] =
+    {   0,
+        0,    0,    2,    2,   47,   45,   40,   38,   32,   45,
+        1,   33,   33,   29,   33,   29,   29,   28,   33,   44,
+       36,   34,   36,   45,   29,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   45,    2,    2,    3,    2,    2,    1,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,   40,   36,    0,   43,   34,   30,   37,   44,    0,
+       41,   44,   44,    0,   35,   39,   42,   42,   42,   42,
+
+       42,   42,   42,   42,   42,   42,   10,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       31,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,   44,    0,    0,   44,    0,   42,   42,   42,   42,
+       42,    9,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,   16,   42,   42,   42,
+       17,   20,   42,   42,   21,   42,   42,   42,   42,    6,
+       42,   18,   42,   42,   12,   22,   42,   42,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        5,   42,   42,   42,   14,   42,   42,   15,   26,   42,
+       42,   13,   42,   11,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,   42,    4,
+       42,    7,   27,   19,    8,   42,    2,    2,    2,    2,
+
+        2,    2,    2,    2,   42,   23,   42,    2,    2,    2,
+       25,   24,    2,    2,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,    5,    6,    1,    7,    8,    1,    9,
+       10,   11,   12,   13,   14,   15,   16,   17,   17,   17,
+       17,   17,   17,   17,   17,   17,   17,    1,   18,   19,
+       20,   21,    1,    1,   22,   22,   22,   22,   22,   22,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+       23,   24,   25,   26,   27,    1,   28,   29,   30,   31,
+
+       32,   33,   34,   35,   36,   37,   38,   39,   40,   41,
+       42,   43,   44,   45,   46,   47,   48,   49,   50,   37,
+       51,   37,   52,   53,   54,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[55] =
+    {   0,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    3,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    1,    1,    1
+    } ;
+
+static yyconst flex_int16_t yy_base[320] =
+    {   0,
+        0,    0,   54,    0,  553,  554,  550,  554,  531,  545,
+      554,  529,  540,  554,  527,   97,   96,   96,  101,  107,
+      526,  116,  525,  541,  523,  494,  496,  498,  507,  499,
+      495,    0,   83,  104,  107,  507,  490,  486,  106,   96,
+      491,  113,  479,    0,  529,  554,  510,  141,    0,  509,
+      520,    0,  507,  133,  135,  130,  139,  141,  506,  150,
+      505,  521,  503,  160,  123,  125,  137,  112,  130,  474,
+      184,  185,  187,  188,  134,  473,  193,  183,  132,  194,
+      467,  517,  554,  513,  554,  554,  554,  554,  221,  514,
+      554,  222,  232,  513,  554,  554,    0,  468,  482,  472,
+
+      479,  465,  465,  470,  462,  479,    0,  460,  464,  464,
+      475,  466,  465,  459,  206,  471,  453,  461,  451,  459,
+      554,    0,  492,    0,  178,    0,    0,    0,    0,  233,
+      490,    0,  241,  244,  489,    0,  443,   67,  192,  189,
+      219,  138,  203,  221,  180,  234,  442,  224,  223,  233,
+      246,  239,  240,  236,  250,  251,  235,  253,  245,  255,
+        0,  278,  486,  287,  288,  485,  445,  458,  438,  448,
+      451,    0,  435,  434,  434,  432,  444,  441,  430,  434,
+      427,  442,  441,  423,  431,  422,  437,  422,  427,  291,
+      462,  297,  461,  244,  268,  259,  281,  286,  415,  275,
+
+      277,  280,  283,  293,  284,  287,  295,  290,  308,  309,
+      414,  303,  297,  315,  302,  310,    0,  423,  424,  418,
+        0,    0,  416,  425,    0,  409,  408,  422,  406,    0,
+      410,    0,  406,  418,    0,    0,  421,  416,  399,  314,
+      312,  313,  398,  397,  311,  323,  396,  317,  319,  336,
+      322,  395,  330,  394,  328,  342,  393,  392,  347,  345,
+        0,  398,  406,  392,    0,  401,  389,    0,    0,  394,
+      392,    0,  391,    0,  383,  338,  348,  337,  382,  346,
+      341,  381,  380,  343,  351,  379,  356,  378,  373,    0,
+      364,    0,    0,    0,    0,  367,  365,  364,  350,  363,
+
+      362,  361,  359,  355,  374,    0,  337,  368,  237,  357,
+        0,    0,  168,  127,  554,  416,  122,  419,  422
+    } ;
+
+static yyconst flex_int16_t yy_def[320] =
+    {   0,
+      315,    1,  315,    3,  315,  315,  315,  315,  315,  316,
+      315,  315,  315,  315,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  317,  317,  317,  317,  317,
+      317,  317,  317,  317,  317,  317,  317,  317,  317,  317,
+      317,  317,  315,  318,  318,  315,  318,  319,  318,  318,
+      318,  318,  318,  318,  318,  318,  318,  318,  318,  318,
+      318,  318,  318,  318,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+      318,  315,  315,  316,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  315,  317,  317,  317,  317,
+
+      317,  317,  317,  317,  317,  317,  317,  317,  317,  317,
+      317,  317,  317,  317,  317,  317,  317,  317,  317,  317,
+      315,  318,  318,  318,  319,  318,  318,  318,  318,  318,
+      318,  318,  318,  318,  318,  318,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+      318,  315,  315,  315,  315,  315,  317,  317,  317,  317,
+      317,  317,  317,  317,  317,  317,  317,  317,  317,  317,
+      317,  317,  317,  317,  317,  317,  317,  317,  317,  318,
+      318,  318,  318,   64,   64,   64,   64,   64,   64,   64,
+
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,  317,  317,  317,  317,
+      317,  317,  317,  317,  317,  317,  317,  317,  317,  317,
+      317,  317,  317,  317,  317,  317,  317,  317,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+      317,  317,  317,  317,  317,  317,  317,  317,  317,  317,
+      317,  317,  317,  317,   64,   64,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,  317,  317,
+      317,  317,  317,  317,  317,  317,   64,   64,   64,   64,
+
+       64,   64,   64,   64,  317,  317,  317,   64,   64,   64,
+      317,  317,   64,   64,    0,  315,  315,  315,  315
+    } ;
+
+static yyconst flex_int16_t yy_nxt[609] =
+    {   0,
+        6,    7,    8,    9,   10,   11,   12,   13,   14,   14,
+       15,   16,   14,   17,   18,   19,   20,   14,   21,   22,
+       23,   20,   14,   24,   14,   25,    6,   26,   27,   28,
+       29,   30,   31,   32,   33,   34,   32,   32,   35,   32,
+       32,   36,   37,   38,   39,   40,   32,   32,   41,   42,
+       32,   14,   43,   14,   44,   45,   46,   47,   48,   49,
+       50,   51,   52,   52,   53,   54,   52,   55,   56,   57,
+       58,   52,   59,   60,   61,   58,   52,   62,   52,   63,
+       44,   64,   65,   66,   67,   68,   69,   70,   71,   72,
+       70,   70,   73,   70,   70,   74,   75,   76,   77,   78,
+
+       70,   70,   79,   80,   70,   52,   81,   52,   88,   88,
+      104,   91,   89,  194,  137,   86,   86,   89,  105,   90,
+       86,   92,   95,   93,   97,  116,   95,   95,   93,   95,
+       94,   95,  106,  114,  108,   83,  107,  115,  109,  117,
+      119,   95,  110,   84,  129,  126,  130,  120,  129,  132,
+      142,  130,  127,  131,  127,  133,  136,  134,  127,  137,
+      136,  136,  134,  136,  135,  136,  140,  139,  141,  124,
+      137,  143,  137,  158,  137,  136,  137,  137,  152,  137,
+       84,  137,  126,  198,  137,  137,  137,  137,  137,  137,
+      137,  137,  137,  137,  137,  137,  137,  137,  137,  137,
+
+      137,  137,  137,  137,  137,  137,  137,  138,  137,  137,
+      137,  144,  156,  146,  148,  137,  151,  147,  149,  145,
+      154,  159,  150,  195,  155,  201,  157,  137,  160,  196,
+      137,  137,  137,  183,  137,  137,  137,  162,  165,  137,
+      137,  137,  162,  165,  163,  166,   92,  199,   93,  190,
+      137,  197,  184,   93,  190,   94,  191,  192,  133,  200,
+      134,  202,  192,  204,  193,  134,  137,  135,  137,  203,
+      137,  137,  205,  206,  207,  208,  209,  210,  212,  213,
+      137,  137,  137,  137,  137,  239,  137,  137,  214,  215,
+      216,  137,  137,  137,  162,  240,  211,  137,  137,  162,
+
+      137,  163,  137,   89,  165,  241,  137,  190,   89,  165,
+       90,  166,  190,  192,  191,  137,  242,  243,  192,  249,
+      193,  244,  137,  245,  137,  246,  248,  137,  137,  247,
+      137,  137,  250,  137,  137,  251,  252,  137,  253,  254,
+      137,  256,  137,  257,  137,  258,  259,  276,  260,  137,
+      137,  275,  278,  277,  279,  137,  137,  137,  137,  137,
+      137,  137,  137,  280,  137,  281,  137,  282,  283,  137,
+      137,  284,  285,  286,  287,  137,  288,  137,  297,  298,
+      300,  299,  302,  137,  137,  137,  301,  312,  137,  137,
+      137,  303,  137,  137,  137,  137,  304,  137,  137,  313,
+
+      309,  310,  137,  137,  137,  311,  137,  314,  137,  137,
+      137,  137,  308,  307,  306,  137,   84,   84,   84,  122,
+      305,  122,  125,  125,  125,  137,  137,  137,  137,  137,
+      137,  296,  295,  294,  293,  292,  291,  290,  289,  137,
+      137,  137,  137,  137,  137,  137,  137,  274,  273,  272,
+      271,  270,  269,  268,  267,  266,  265,  264,  263,  262,
+      261,  255,  137,  165,  162,  238,  237,  236,  235,  234,
+      233,  232,  231,  230,  229,  228,  227,  226,  225,  224,
+      223,  222,  221,  220,  219,  218,  217,  165,  162,  137,
+      137,   93,  164,  123,  189,  188,  187,  186,  185,  182,
+
+      181,  180,  179,  178,  177,  176,  175,  174,  173,  172,
+      171,  170,  169,  168,  167,   93,  164,   85,   82,  161,
+      153,  137,  127,   96,  124,  124,  127,  128,  127,  124,
+      123,  121,  118,  113,  112,  111,  103,  102,  101,  100,
+       99,   98,   86,   96,   83,   83,   86,   87,   86,   85,
+       83,   82,  315,    5,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  315,  315,  315,  315,  315,
+
+      315,  315,  315,  315,  315,  315,  315,  315
+    } ;
+
+static yyconst flex_int16_t yy_chk[609] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+
+        3,    3,    3,    3,    3,    3,    3,    3,   16,   17,
+       33,   19,   18,  138,  138,   17,   16,   18,   33,   18,
+       19,   20,   22,   20,  317,   40,   22,   22,   20,   22,
+       20,   22,   34,   39,   35,   22,   34,   39,   35,   40,
+       42,   22,   35,   48,   54,   48,   56,   42,   55,   57,
+       68,   56,   54,   56,   55,   58,   60,   58,   57,   68,
+       60,   60,   58,   60,   58,   60,   66,   65,   67,   60,
+       65,   69,   66,   79,  314,   60,   64,   69,   75,   79,
+      125,   75,  125,  142,   67,  142,   64,   64,   64,   64,
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+
+       64,   64,   64,   64,   64,   64,   64,   64,   64,   64,
+       64,   71,   78,   72,   73,  313,   74,   72,   73,   71,
+       77,   80,   73,  139,   77,  145,   78,  145,   80,  140,
+       78,   71,   72,  115,   73,   74,  140,   89,   92,  139,
+       77,   80,   89,   92,   89,   92,   93,  143,   93,  130,
+      143,  141,  115,   93,  130,   93,  130,  133,  134,  144,
+      134,  146,  133,  149,  133,  134,  141,  134,  144,  148,
+      149,  148,  150,  151,  152,  153,  154,  155,  156,  157,
+      150,  146,  157,  154,  309,  194,  152,  153,  158,  159,
+      160,  194,  159,  151,  162,  195,  155,  155,  156,  162,
+
+      158,  162,  160,  164,  165,  196,  196,  190,  164,  165,
+      164,  165,  190,  192,  190,  195,  197,  198,  192,  205,
+      192,  200,  200,  201,  201,  202,  204,  202,  197,  203,
+      203,  205,  206,  198,  206,  207,  208,  208,  209,  210,
+      204,  212,  207,  213,  213,  214,  215,  241,  216,  215,
+      212,  240,  245,  242,  246,  209,  210,  216,  245,  241,
+      242,  240,  214,  248,  248,  249,  249,  250,  251,  251,
+      246,  253,  255,  256,  259,  255,  260,  253,  276,  277,
+      280,  278,  284,  250,  278,  276,  281,  307,  281,  256,
+      284,  285,  260,  280,  259,  277,  287,  299,  285,  308,
+
+      299,  304,  304,  287,  310,  305,  303,  310,  302,  301,
+      300,  298,  297,  296,  291,  308,  316,  316,  316,  318,
+      289,  318,  319,  319,  319,  288,  286,  283,  282,  279,
+      275,  273,  271,  270,  267,  266,  264,  263,  262,  258,
+      257,  254,  252,  247,  244,  243,  239,  238,  237,  234,
+      233,  231,  229,  228,  227,  226,  224,  223,  220,  219,
+      218,  211,  199,  193,  191,  189,  188,  187,  186,  185,
+      184,  183,  182,  181,  180,  179,  178,  177,  176,  175,
+      174,  173,  171,  170,  169,  168,  167,  166,  163,  147,
+      137,  135,  131,  123,  120,  119,  118,  117,  116,  114,
+
+      113,  112,  111,  110,  109,  108,  106,  105,  104,  103,
+      102,  101,  100,   99,   98,   94,   90,   84,   82,   81,
+       76,   70,   63,   62,   61,   59,   53,   51,   50,   47,
+       45,   43,   41,   38,   37,   36,   31,   30,   29,   28,
+       27,   26,   25,   24,   23,   21,   15,   13,   12,   10,
+        9,    7,    5,  315,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  315,  315,  315,  315,  315,
+      315,  315,  315,  315,  315,  315,  315,  315,  315,  315,
+
+      315,  315,  315,  315,  315,  315,  315,  315
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "scan.l"
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+/* scan.l: the (f)lex description file for the scanner. */
+#line 33 "scan.l"
+
+#include "bcdefs.h"
+#include "bc.h"
+#include "global.h"
+#include "proto.h"
+#include <errno.h>
+
+/* Using flex, we can ask for a smaller input buffer.  With lex, this
+   does nothing! */
+
+#ifdef SMALL_BUF
+#undef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 512
+#endif
+
+/* Force . as last for now. */
+#define DOT_IS_LAST
+
+/* We want to define our own yywrap. */
+#undef yywrap
+_PROTOTYPE(int yywrap, (void));
+
+#if defined(LIBEDIT)
+/* Support for the BSD libedit with history for
+   nicer input on the interactive part of input. */
+
+#include <histedit.h>
+
+/* Have input call the following function. */
+#undef  YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+               bcel_input((char *)buf, &result, max_size)
+
+/* Variables to help interface editline with bc. */
+static const char *bcel_line = (char *)NULL;
+static int   bcel_len = 0;
+
+
+/* Required to get rid of that ugly ? default prompt! */
+char *
+null_prompt (EditLine *el)
+{
+  return "";
+}
+
+
+/* bcel_input puts upto MAX characters into BUF with the number put in
+   BUF placed in *RESULT.  If the yy input file is the same as
+   stdin, use editline.  Otherwise, just read it.
+*/
+
+static void
+bcel_input (buf, result, max)
+       char *buf;
+       int  *result;
+       int   max;
+{
+  if (!edit || yyin != stdin)
+    {
+      while ( (*result = read( fileno(yyin), buf, max )) < 0 )
+        if (errno != EINTR)
+         {
+           yyerror( "read() in flex scanner failed" );
+           exit (1);
+         }
+      return;
+    }
+
+  /* Do we need a new string? */
+  if (bcel_len == 0)
+    {
+      bcel_line = el_gets(edit, &bcel_len);
+      if (bcel_line == NULL) {
+       /* end of file */
+       *result = 0;
+       bcel_len = 0;
+       return;
+      }
+      if (bcel_len != 0)
+       history (hist, &histev, H_ENTER, bcel_line); 
+      fflush (stdout);
+    }
+
+  if (bcel_len <= max)
+    {
+      strncpy (buf, bcel_line, bcel_len);
+      *result = bcel_len;
+      bcel_len = 0;
+    }
+  else
+    {
+      strncpy (buf, bcel_line, max);
+      *result = max;
+      bcel_line += max;
+      bcel_len -= max;
+    }
+}
+#endif
+
+#ifdef READLINE
+/* Support for the readline and history libraries.  This allows
+   nicer input on the interactive part of input. */
+
+/* Have input call the following function. */
+#undef  YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+               rl_input((char *)buf, &result, max_size)
+
+/* Variables to help interface readline with bc. */
+static char *rl_line = (char *)NULL;
+static char *rl_start = (char *)NULL;
+static int   rl_len = 0;
+
+/* Definitions for readline access. */
+extern FILE *rl_instream;
+
+/* rl_input puts upto MAX characters into BUF with the number put in
+   BUF placed in *RESULT.  If the yy input file is the same as
+   rl_instream (stdin), use readline.  Otherwise, just read it.
+*/
+
+static void
+rl_input (buf, result, max)
+       char *buf;
+       int  *result;
+       int   max;
+{
+  if (yyin != rl_instream)
+    {
+      while ( (*result = read( fileno(yyin), buf, max )) < 0 )
+        if (errno != EINTR)
+         {
+           yyerror( "read() in flex scanner failed" );
+           exit (1);
+         }
+      return;
+    }
+
+  /* Do we need a new string? */
+  if (rl_len == 0)
+    {
+      if (rl_start)
+       free(rl_start);
+      rl_start = readline ("");
+      if (rl_start == NULL) {
+       /* end of file */
+       *result = 0;
+       rl_len = 0;
+       return;
+      }
+      rl_line = rl_start;
+      rl_len = strlen (rl_line)+1;
+      if (rl_len != 1)
+       add_history (rl_line); 
+      rl_line[rl_len-1] = '\n';
+      fflush (stdout);
+    }
+
+  if (rl_len <= max)
+    {
+      strncpy (buf, rl_line, rl_len);
+      *result = rl_len;
+      rl_len = 0;
+    }
+  else
+    {
+      strncpy (buf, rl_line, max);
+      *result = max;
+      rl_line += max;
+      rl_len -= max;
+    }
+}
+#endif
+
+#if !defined(READLINE) && !defined(LIBEDIT)
+
+/* MINIX returns from read with < 0 if SIGINT is  encountered.
+   In flex, we can redefine YY_INPUT to the following.  In lex, this
+   does nothing! */
+#undef  YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+       while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
+           if (errno != EINTR) \
+               YY_FATAL_ERROR( "read() in flex scanner failed" );
+#endif
+
+
+#line 909 "scan.c"
+
+#define INITIAL 0
+#define slcomment 1
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  );
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+               { \
+               int c = '*'; \
+               size_t n; \
+               for ( n = 0; n < max_size && \
+                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+                       buf[n] = (char) c; \
+               if ( c == '\n' ) \
+                       buf[n++] = (char) c; \
+               if ( c == EOF && ferror( yyin ) ) \
+                       YY_FATAL_ERROR( "input in flex scanner failed" ); \
+               result = n; \
+               } \
+       else \
+               { \
+               errno=0; \
+               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+                       { \
+                       if( errno != EINTR) \
+                               { \
+                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
+                               break; \
+                               } \
+                       errno=0; \
+                       clearerr(yyin); \
+                       } \
+               }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+       YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp, *yy_bp;
+       register int yy_act;
+    
+#line 223 "scan.l"
+
+#line 1065 "scan.c"
+
+       if ( !(yy_init) )
+               {
+               (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+               YY_USER_INIT;
+#endif
+
+               if ( ! (yy_start) )
+                       (yy_start) = 1; /* first start state */
+
+               if ( ! yyin )
+                       yyin = stdin;
+
+               if ( ! yyout )
+                       yyout = stdout;
+
+               if ( ! YY_CURRENT_BUFFER ) {
+                       yyensure_buffer_stack ();
+                       YY_CURRENT_BUFFER_LVALUE =
+                               yy_create_buffer(yyin,YY_BUF_SIZE );
+               }
+
+               yy_load_buffer_state( );
+               }
+
+       while ( 1 )             /* loops until end-of-file is reached */
+               {
+               yy_cp = (yy_c_buf_p);
+
+               /* Support of yytext. */
+               *yy_cp = (yy_hold_char);
+
+               /* yy_bp points to the position in yy_ch_buf of the start of
+                * the current run.
+                */
+               yy_bp = yy_cp;
+
+               yy_current_state = (yy_start);
+yy_match:
+               do
+                       {
+                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+                       if ( yy_accept[yy_current_state] )
+                               {
+                               (yy_last_accepting_state) = yy_current_state;
+                               (yy_last_accepting_cpos) = yy_cp;
+                               }
+                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                               {
+                               yy_current_state = (int) yy_def[yy_current_state];
+                               if ( yy_current_state >= 316 )
+                                       yy_c = yy_meta[(unsigned int) yy_c];
+                               }
+                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+                       ++yy_cp;
+                       }
+               while ( yy_base[yy_current_state] != 554 );
+
+yy_find_action:
+               yy_act = yy_accept[yy_current_state];
+               if ( yy_act == 0 )
+                       { /* have to back up */
+                       yy_cp = (yy_last_accepting_cpos);
+                       yy_current_state = (yy_last_accepting_state);
+                       yy_act = yy_accept[yy_current_state];
+                       }
+
+               YY_DO_BEFORE_ACTION;
+
+do_action:     /* This label is used only to access EOF actions. */
+
+               switch ( yy_act )
+       { /* beginning of action switch */
+                       case 0: /* must back up */
+                       /* undo the effects of YY_DO_BEFORE_ACTION */
+                       *yy_cp = (yy_hold_char);
+                       yy_cp = (yy_last_accepting_cpos);
+                       yy_current_state = (yy_last_accepting_state);
+                       goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 224 "scan.l"
+{
+                 if (!std_only)
+                   BEGIN(slcomment);
+                 else
+                   yyerror ("illegal character: #");
+               }
+       YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 230 "scan.l"
+{ BEGIN(INITIAL); }
+       YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 231 "scan.l"
+{ line_no++; BEGIN(INITIAL); return(ENDOFLINE); }
+       YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 232 "scan.l"
+return(Define);
+       YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 233 "scan.l"
+return(Break);
+       YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 234 "scan.l"
+return(Quit);
+       YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 235 "scan.l"
+return(Length);
+       YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 236 "scan.l"
+return(Return);
+       YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 237 "scan.l"
+return(For);
+       YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 238 "scan.l"
+return(If);
+       YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 239 "scan.l"
+return(While);
+       YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 240 "scan.l"
+return(Sqrt);
+       YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 241 "scan.l"
+return(Scale);
+       YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 242 "scan.l"
+return(Ibase);
+       YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 243 "scan.l"
+return(Obase);
+       YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 244 "scan.l"
+return(Auto);
+       YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 245 "scan.l"
+return(Else);
+       YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 246 "scan.l"
+return(Read);
+       YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 247 "scan.l"
+return(Random);
+       YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 248 "scan.l"
+return(Halt);
+       YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 249 "scan.l"
+return(Last);
+       YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 250 "scan.l"
+return(Void); 
+       YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 251 "scan.l"
+{
+#if defined(READLINE) || defined(LIBEDIT)
+         return(HistoryVar);
+#else
+         yylval.s_value = strcopyof(yytext); return(NAME);
+#endif
+       }
+       YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 259 "scan.l"
+return(Warranty);
+       YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 260 "scan.l"
+return(Continue);
+       YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 261 "scan.l"
+return(Print);
+       YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 262 "scan.l"
+return(Limits);
+       YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 263 "scan.l"
+{
+#ifdef DOT_IS_LAST
+       return(Last);
+#else
+       yyerror ("illegal character: %s",yytext);
+#endif
+    }
+       YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 270 "scan.l"
+{ yylval.c_value = yytext[0]; 
+                                             return((int)yytext[0]); }
+       YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 272 "scan.l"
+{ return(AND); }
+       YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 273 "scan.l"
+{ return(OR); }
+       YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 274 "scan.l"
+{ return(NOT); }
+       YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 275 "scan.l"
+{ yylval.c_value = yytext[0]; return((int)yytext[0]); }
+       YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 276 "scan.l"
+{ yylval.c_value = yytext[0]; return(ASSIGN_OP); }
+       YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 277 "scan.l"
+{ 
+#ifdef OLD_EQ_OP
+                        char warn_save;
+                        warn_save = warn_not_std;
+                        warn_not_std = TRUE;
+                        warn ("Old fashioned =<op>");
+                        warn_not_std = warn_save;
+                        yylval.c_value = yytext[1];
+#else
+                        yylval.c_value = '=';
+                        yyless (1);
+#endif
+                        return(ASSIGN_OP);
+                      }
+       YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 291 "scan.l"
+{ yylval.s_value = strcopyof(yytext); return(REL_OP); }
+       YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 292 "scan.l"
+{ yylval.c_value = yytext[0]; return(INCR_DECR); }
+       YY_BREAK
+case 38:
+/* rule 38 can match eol */
+YY_RULE_SETUP
+#line 293 "scan.l"
+{ line_no++; return(ENDOFLINE); }
+       YY_BREAK
+case 39:
+/* rule 39 can match eol */
+YY_RULE_SETUP
+#line 294 "scan.l"
+{  line_no++;  /* ignore a "quoted" newline */ }
+       YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 295 "scan.l"
+{ /* ignore spaces and tabs */ }
+       YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 296 "scan.l"
+{
+       int c;
+
+       for (;;)
+         {
+           while ( ((c=input()) != '*') && (c != EOF)) 
+             /* eat it */
+             if (c == '\n') line_no++;
+           if (c == '*')
+             {
+               while ( (c=input()) == '*') /* eat it*/;
+               if (c == '/') break; /* at end of comment */
+               if (c == '\n') line_no++;
+             }
+           if (c == EOF)
+             {
+               fprintf (stderr,"EOF encountered in a comment.\n");
+               break;
+             }
+         }
+      }
+       YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 317 "scan.l"
+{ yylval.s_value = strcopyof(yytext); return(NAME); }
+       YY_BREAK
+case 43:
+/* rule 43 can match eol */
+YY_RULE_SETUP
+#line 318 "scan.l"
+{
+             const char *look;
+             int count = 0;
+             yylval.s_value = strcopyof(yytext);
+             for (look = yytext; *look != 0; look++)
+               {
+                 if (*look == '\n') line_no++;
+                 if (*look == '"')  count++;
+               }
+             if (count != 2) yyerror ("NUL character in string.");
+             return(STRING);
+           }
+       YY_BREAK
+case 44:
+/* rule 44 can match eol */
+YY_RULE_SETUP
+#line 330 "scan.l"
+{
+             char *src, *dst;
+             int len;
+             /* remove a trailing decimal point. */
+             len = strlen(yytext);
+             if (yytext[len-1] == '.')
+               yytext[len-1] = 0;
+             /* remove leading zeros. */
+             src = yytext;
+             dst = yytext;
+             while (*src == '0') src++;
+             if (*src == 0) src--;
+             /* Copy strings removing the newlines. */
+             while (*src != 0)
+               {
+                 if (*src == '\\')
+                   {
+                     src++; src++;
+                     line_no++;
+                   }
+                 else
+                   *dst++ = *src++;
+               }
+             *dst = 0;
+             yylval.s_value = strcopyof(yytext); 
+             return(NUMBER);
+           }
+       YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 357 "scan.l"
+{
+         if (yytext[0] < ' ')
+           yyerror ("illegal character: ^%c",yytext[0] + '@');
+         else
+           if (yytext[0] > '~')
+             yyerror ("illegal character: \\%03o", (int) yytext[0]);
+           else
+             yyerror ("illegal character: %s",yytext);
+       }
+       YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 366 "scan.l"
+ECHO;
+       YY_BREAK
+#line 1479 "scan.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(slcomment):
+       yyterminate();
+
+       case YY_END_OF_BUFFER:
+               {
+               /* Amount of text matched not including the EOB char. */
+               int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */
+               *yy_cp = (yy_hold_char);
+               YY_RESTORE_YY_MORE_OFFSET
+
+               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+                       {
+                       /* We're scanning a new file or input source.  It's
+                        * possible that this happened because the user
+                        * just pointed yyin at a new source and called
+                        * yylex().  If so, then we have to assure
+                        * consistency between YY_CURRENT_BUFFER and our
+                        * globals.  Here is the right place to do so, because
+                        * this is the first action (other than possibly a
+                        * back-up) that will match for the new input source.
+                        */
+                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+                       }
+
+               /* Note that here we test for yy_c_buf_p "<=" to the position
+                * of the first EOB in the buffer, since yy_c_buf_p will
+                * already have been incremented past the NUL character
+                * (since all states make transitions on EOB to the
+                * end-of-buffer state).  Contrast this with the test
+                * in input().
+                */
+               if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+                       { /* This was really a NUL. */
+                       yy_state_type yy_next_state;
+
+                       (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+                       yy_current_state = yy_get_previous_state(  );
+
+                       /* Okay, we're now positioned to make the NUL
+                        * transition.  We couldn't have
+                        * yy_get_previous_state() go ahead and do it
+                        * for us because it doesn't know how to deal
+                        * with the possibility of jamming (and we don't
+                        * want to build jamming into it because then it
+                        * will run more slowly).
+                        */
+
+                       yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+                       yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+                       if ( yy_next_state )
+                               {
+                               /* Consume the NUL. */
+                               yy_cp = ++(yy_c_buf_p);
+                               yy_current_state = yy_next_state;
+                               goto yy_match;
+                               }
+
+                       else
+                               {
+                               yy_cp = (yy_c_buf_p);
+                               goto yy_find_action;
+                               }
+                       }
+
+               else switch ( yy_get_next_buffer(  ) )
+                       {
+                       case EOB_ACT_END_OF_FILE:
+                               {
+                               (yy_did_buffer_switch_on_eof) = 0;
+
+                               if ( yywrap( ) )
+                                       {
+                                       /* Note: because we've taken care in
+                                        * yy_get_next_buffer() to have set up
+                                        * yytext, we can now set up
+                                        * yy_c_buf_p so that if some total
+                                        * hoser (like flex itself) wants to
+                                        * call the scanner after we return the
+                                        * YY_NULL, it'll still work - another
+                                        * YY_NULL will get returned.
+                                        */
+                                       (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+                                       yy_act = YY_STATE_EOF(YY_START);
+                                       goto do_action;
+                                       }
+
+                               else
+                                       {
+                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                               YY_NEW_FILE;
+                                       }
+                               break;
+                               }
+
+                       case EOB_ACT_CONTINUE_SCAN:
+                               (yy_c_buf_p) =
+                                       (yytext_ptr) + yy_amount_of_matched_text;
+
+                               yy_current_state = yy_get_previous_state(  );
+
+                               yy_cp = (yy_c_buf_p);
+                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               goto yy_match;
+
+                       case EOB_ACT_LAST_MATCH:
+                               (yy_c_buf_p) =
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+                               yy_current_state = yy_get_previous_state(  );
+
+                               yy_cp = (yy_c_buf_p);
+                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               goto yy_find_action;
+                       }
+               break;
+               }
+
+       default:
+               YY_FATAL_ERROR(
+                       "fatal flex scanner internal error--no action found" );
+       } /* end of action switch */
+               } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *     EOB_ACT_LAST_MATCH -
+ *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *     EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+       register char *source = (yytext_ptr);
+       register int number_to_move, i;
+       int ret_val;
+
+       if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+               YY_FATAL_ERROR(
+               "fatal flex scanner internal error--end of buffer missed" );
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+               { /* Don't try to fill the buffer, so this is an EOF. */
+               if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+                       {
+                       /* We matched a single character, the EOB, so
+                        * treat this as a final EOF.
+                        */
+                       return EOB_ACT_END_OF_FILE;
+                       }
+
+               else
+                       {
+                       /* We matched some text prior to the EOB, first
+                        * process it.
+                        */
+                       return EOB_ACT_LAST_MATCH;
+                       }
+               }
+
+       /* Try to read more data. */
+
+       /* First move last chars to start of buffer. */
+       number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+       for ( i = 0; i < number_to_move; ++i )
+               *(dest++) = *(source++);
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+               /* don't do the read, it's not guaranteed to return an EOF,
+                * just force an EOF
+                */
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+       else
+               {
+                       int num_to_read =
+                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+               while ( num_to_read <= 0 )
+                       { /* Not enough room in the buffer - grow it. */
+
+                       /* just a shorter name for the current buffer */
+                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+                       int yy_c_buf_p_offset =
+                               (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+                       if ( b->yy_is_our_buffer )
+                               {
+                               int new_size = b->yy_buf_size * 2;
+
+                               if ( new_size <= 0 )
+                                       b->yy_buf_size += b->yy_buf_size / 8;
+                               else
+                                       b->yy_buf_size *= 2;
+
+                               b->yy_ch_buf = (char *)
+                                       /* Include room in for 2 EOB chars. */
+                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+                               }
+                       else
+                               /* Can't grow it, we don't own it. */
+                               b->yy_ch_buf = 0;
+
+                       if ( ! b->yy_ch_buf )
+                               YY_FATAL_ERROR(
+                               "fatal error - scanner input buffer overflow" );
+
+                       (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                                               number_to_move - 1;
+
+                       }
+
+               if ( num_to_read > YY_READ_BUF_SIZE )
+                       num_to_read = YY_READ_BUF_SIZE;
+
+               /* Read in more data. */
+               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+                       (yy_n_chars), num_to_read );
+
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       if ( (yy_n_chars) == 0 )
+               {
+               if ( number_to_move == YY_MORE_ADJ )
+                       {
+                       ret_val = EOB_ACT_END_OF_FILE;
+                       yyrestart(yyin  );
+                       }
+
+               else
+                       {
+                       ret_val = EOB_ACT_LAST_MATCH;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                               YY_BUFFER_EOF_PENDING;
+                       }
+               }
+
+       else
+               ret_val = EOB_ACT_CONTINUE_SCAN;
+
+       (yy_n_chars) += number_to_move;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+       (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+       return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp;
+    
+       yy_current_state = (yy_start);
+
+       for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+               {
+               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+               if ( yy_accept[yy_current_state] )
+                       {
+                       (yy_last_accepting_state) = yy_current_state;
+                       (yy_last_accepting_cpos) = yy_cp;
+                       }
+               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                       {
+                       yy_current_state = (int) yy_def[yy_current_state];
+                       if ( yy_current_state >= 316 )
+                               yy_c = yy_meta[(unsigned int) yy_c];
+                       }
+               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+               }
+
+       return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *     next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+       register int yy_is_jam;
+       register char *yy_cp = (yy_c_buf_p);
+
+       register YY_CHAR yy_c = 1;
+       if ( yy_accept[yy_current_state] )
+               {
+               (yy_last_accepting_state) = yy_current_state;
+               (yy_last_accepting_cpos) = yy_cp;
+               }
+       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+               {
+               yy_current_state = (int) yy_def[yy_current_state];
+               if ( yy_current_state >= 316 )
+                       yy_c = yy_meta[(unsigned int) yy_c];
+               }
+       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+       yy_is_jam = (yy_current_state == 315);
+
+       return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp )
+{
+       register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+       /* undo effects of setting up yytext */
+       *yy_cp = (yy_hold_char);
+
+       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+               { /* need to shift things up to make room */
+               /* +2 for EOB chars. */
+               register int number_to_move = (yy_n_chars) + 2;
+               register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+               register char *source =
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       *--dest = *--source;
+
+               yy_cp += (int) (dest - source);
+               yy_bp += (int) (dest - source);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
+               }
+
+       *--yy_cp = (char) c;
+
+       (yytext_ptr) = yy_bp;
+       (yy_hold_char) = *yy_cp;
+       (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+       int c;
+    
+       *(yy_c_buf_p) = (yy_hold_char);
+
+       if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+               {
+               /* yy_c_buf_p now points to the character we want to return.
+                * If this occurs *before* the EOB characters, then it's a
+                * valid NUL; if not, then we've hit the end of the buffer.
+                */
+               if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+                       /* This was really a NUL. */
+                       *(yy_c_buf_p) = '\0';
+
+               else
+                       { /* need more input */
+                       int offset = (yy_c_buf_p) - (yytext_ptr);
+                       ++(yy_c_buf_p);
+
+                       switch ( yy_get_next_buffer(  ) )
+                               {
+                               case EOB_ACT_LAST_MATCH:
+                                       /* This happens because yy_g_n_b()
+                                        * sees that we've accumulated a
+                                        * token and flags that we need to
+                                        * try matching the token before
+                                        * proceeding.  But for input(),
+                                        * there's no matching to consider.
+                                        * So convert the EOB_ACT_LAST_MATCH
+                                        * to EOB_ACT_END_OF_FILE.
+                                        */
+
+                                       /* Reset buffer status. */
+                                       yyrestart(yyin );
+
+                                       /*FALLTHROUGH*/
+
+                               case EOB_ACT_END_OF_FILE:
+                                       {
+                                       if ( yywrap( ) )
+                                               return EOF;
+
+                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                               YY_NEW_FILE;
+#ifdef __cplusplus
+                                       return yyinput();
+#else
+                                       return input();
+#endif
+                                       }
+
+                               case EOB_ACT_CONTINUE_SCAN:
+                                       (yy_c_buf_p) = (yytext_ptr) + offset;
+                                       break;
+                               }
+                       }
+               }
+
+       c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
+       *(yy_c_buf_p) = '\0';   /* preserve yytext */
+       (yy_hold_char) = *++(yy_c_buf_p);
+
+       return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyrestart  (FILE * input_file )
+{
+    
+       if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack ();
+               YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer(yyin,YY_BUF_SIZE );
+       }
+
+       yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+       yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+       /* TODO. We should be able to replace this entire function body
+        * with
+        *              yypop_buffer_state();
+        *              yypush_buffer_state(new_buffer);
+     */
+       yyensure_buffer_stack ();
+       if ( YY_CURRENT_BUFFER == new_buffer )
+               return;
+
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *(yy_c_buf_p) = (yy_hold_char);
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+       yy_load_buffer_state( );
+
+       /* We don't actually know whether we did this switch during
+        * EOF (yywrap()) processing, but the only time this flag
+        * is looked at is after yywrap() is called, so it's safe
+        * to go ahead and always set it.
+        */
+       (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state  (void)
+{
+       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+       (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+       (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
+{
+       YY_BUFFER_STATE b;
+    
+       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_buf_size = size;
+
+       /* yy_ch_buf has to be 2 characters longer than the size given because
+        * we need to put in 2 end-of-buffer characters.
+        */
+       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+       if ( ! b->yy_ch_buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_is_our_buffer = 1;
+
+       yy_init_buffer(b,file );
+
+       return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * 
+ */
+    void yy_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+       if ( ! b )
+               return;
+
+       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+       if ( b->yy_is_our_buffer )
+               yyfree((void *) b->yy_ch_buf  );
+
+       yyfree((void *) b  );
+}
+
+#ifndef _UNISTD_H /* assume unistd.h has isatty() for us */
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __THROW /* this is a gnuism */
+extern int isatty (int ) __THROW;
+#else
+extern int isatty (int );
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+       int oerrno = errno;
+    
+       yy_flush_buffer(b );
+
+       b->yy_input_file = file;
+       b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+       errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void yy_flush_buffer (YY_BUFFER_STATE  b )
+{
+       if ( ! b )
+               return;
+
+       b->yy_n_chars = 0;
+
+       /* We always need two end-of-buffer characters.  The first causes
+        * a transition to the end-of-buffer state.  The second causes
+        * a jam in that state.
+        */
+       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+       b->yy_buf_pos = &b->yy_ch_buf[0];
+
+       b->yy_at_bol = 1;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       if ( b == YY_CURRENT_BUFFER )
+               yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+       if (new_buffer == NULL)
+               return;
+
+       yyensure_buffer_stack();
+
+       /* This block is copied from yy_switch_to_buffer. */
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *(yy_c_buf_p) = (yy_hold_char);
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       /* Only push if top exists. Otherwise, replace top. */
+       if (YY_CURRENT_BUFFER)
+               (yy_buffer_stack_top)++;
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+       /* copied from yy_switch_to_buffer. */
+       yy_load_buffer_state( );
+       (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void yypop_buffer_state (void)
+{
+       if (!YY_CURRENT_BUFFER)
+               return;
+
+       yy_delete_buffer(YY_CURRENT_BUFFER );
+       YY_CURRENT_BUFFER_LVALUE = NULL;
+       if ((yy_buffer_stack_top) > 0)
+               --(yy_buffer_stack_top);
+
+       if (YY_CURRENT_BUFFER) {
+               yy_load_buffer_state( );
+               (yy_did_buffer_switch_on_eof) = 1;
+       }
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+       int num_to_alloc;
+    
+       if (!(yy_buffer_stack)) {
+
+               /* First allocation is just for 2 elements, since we don't know if this
+                * scanner will even need a stack. We use 2 instead of 1 to avoid an
+                * immediate realloc on the next call.
+         */
+               num_to_alloc = 1;
+               (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               );
+               
+               memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+                               
+               (yy_buffer_stack_max) = num_to_alloc;
+               (yy_buffer_stack_top) = 0;
+               return;
+       }
+
+       if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+               /* Increase the buffer to prepare for a possible push. */
+               int grow_size = 8 /* arbitrary grow size */;
+
+               num_to_alloc = (yy_buffer_stack_max) + grow_size;
+               (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+                                                               ((yy_buffer_stack),
+                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               );
+
+               /* zero only the new slots.*/
+               memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+               (yy_buffer_stack_max) = num_to_alloc;
+       }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
+{
+       YY_BUFFER_STATE b;
+    
+       if ( size < 2 ||
+            base[size-2] != YY_END_OF_BUFFER_CHAR ||
+            base[size-1] != YY_END_OF_BUFFER_CHAR )
+               /* They forgot to leave room for the EOB's. */
+               return 0;
+
+       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
+       b->yy_buf_pos = b->yy_ch_buf = base;
+       b->yy_is_our_buffer = 0;
+       b->yy_input_file = 0;
+       b->yy_n_chars = b->yy_buf_size;
+       b->yy_is_interactive = 0;
+       b->yy_at_bol = 1;
+       b->yy_fill_buffer = 0;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       yy_switch_to_buffer(b  );
+
+       return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * __yystr )
+{
+    
+       return yy_scan_bytes(__yystr,strlen(__yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+       YY_BUFFER_STATE b;
+       char *buf;
+       yy_size_t n;
+       int i;
+    
+       /* Get memory for full buffer, including space for trailing EOB's. */
+       n = _yybytes_len + 2;
+       buf = (char *) yyalloc(n  );
+       if ( ! buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+       for ( i = 0; i < _yybytes_len; ++i )
+               buf[i] = yybytes[i];
+
+       buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+       b = yy_scan_buffer(buf,n );
+       if ( ! b )
+               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+       /* It's okay to grow etc. this buffer, and we should throw it
+        * away when we're done.
+        */
+       b->yy_is_our_buffer = 1;
+
+       return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               yytext[yyleng] = (yy_hold_char); \
+               (yy_c_buf_p) = yytext + yyless_macro_arg; \
+               (yy_hold_char) = *(yy_c_buf_p); \
+               *(yy_c_buf_p) = '\0'; \
+               yyleng = yyless_macro_arg; \
+               } \
+       while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int yyget_lineno  (void)
+{
+        
+    return yylineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *yyget_in  (void)
+{
+        return yyin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *yyget_out  (void)
+{
+        return yyout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int yyget_leng  (void)
+{
+        return yyleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *yyget_text  (void)
+{
+        return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void yyset_lineno (int  line_number )
+{
+    
+    yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE *  in_str )
+{
+        yyin = in_str ;
+}
+
+void yyset_out (FILE *  out_str )
+{
+        yyout = out_str ;
+}
+
+int yyget_debug  (void)
+{
+        return yy_flex_debug;
+}
+
+void yyset_debug (int  bdebug )
+{
+        yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from yylex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * yylex_init()
+     */
+    return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+       while(YY_CURRENT_BUFFER){
+               yy_delete_buffer(YY_CURRENT_BUFFER  );
+               YY_CURRENT_BUFFER_LVALUE = NULL;
+               yypop_buffer_state();
+       }
+
+       /* Destroy the stack itself. */
+       yyfree((yy_buffer_stack) );
+       (yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * yylex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+       register int i;
+       for ( i = 0; i < n; ++i )
+               s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+       register int n;
+       for ( n = 0; s[n]; ++n )
+               ;
+
+       return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size )
+{
+       return (void *) malloc( size );
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size )
+{
+       /* The cast to (char *) in the following accommodates both
+        * implementations that use char* generic pointers, and those
+        * that use void* generic pointers.  It works with the latter
+        * because both ANSI C and C++ allow castless assignment from
+        * any pointer type to void*, and deal with argument conversions
+        * as though doing an assignment.
+        */
+       return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 366 "scan.l"
+
+
+
+
+
+/* This is the way to get multiple files input into lex. */
+
+int
+yywrap()
+{
+  if (!open_new_file ()) return (1);   /* EOF on standard in. */
+  return (0);                          /* We have more input. */
+}
+
diff --git a/bc/scan.l b/bc/scan.l
new file mode 100644 (file)
index 0000000..841c3df
--- /dev/null
+++ b/bc/scan.l
@@ -0,0 +1,377 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* scan.l: the (f)lex description file for the scanner. */
+
+%{
+
+#include "bcdefs.h"
+#include "bc.h"
+#include "global.h"
+#include "proto.h"
+#include <errno.h>
+
+/* Using flex, we can ask for a smaller input buffer.  With lex, this
+   does nothing! */
+
+#ifdef SMALL_BUF
+#undef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 512
+#endif
+
+/* Force . as last for now. */
+#define DOT_IS_LAST
+
+/* We want to define our own yywrap. */
+#undef yywrap
+_PROTOTYPE(int yywrap, (void));
+
+#if defined(LIBEDIT)
+/* Support for the BSD libedit with history for
+   nicer input on the interactive part of input. */
+
+#include <histedit.h>
+
+/* Have input call the following function. */
+#undef  YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+               bcel_input((char *)buf, &result, max_size)
+
+/* Variables to help interface editline with bc. */
+static const char *bcel_line = (char *)NULL;
+static int   bcel_len = 0;
+
+
+/* Required to get rid of that ugly ? default prompt! */
+char *
+null_prompt (EditLine *el)
+{
+  return "";
+}
+
+
+/* bcel_input puts upto MAX characters into BUF with the number put in
+   BUF placed in *RESULT.  If the yy input file is the same as
+   stdin, use editline.  Otherwise, just read it.
+*/
+
+static void
+bcel_input (buf, result, max)
+       char *buf;
+       int  *result;
+       int   max;
+{
+  if (!edit || yyin != stdin)
+    {
+      while ( (*result = read( fileno(yyin), buf, max )) < 0 )
+        if (errno != EINTR)
+         {
+           yyerror( "read() in flex scanner failed" );
+           exit (1);
+         }
+      return;
+    }
+
+  /* Do we need a new string? */
+  if (bcel_len == 0)
+    {
+      bcel_line = el_gets(edit, &bcel_len);
+      if (bcel_line == NULL) {
+       /* end of file */
+       *result = 0;
+       bcel_len = 0;
+       return;
+      }
+      if (bcel_len != 0)
+       history (hist, &histev, H_ENTER, bcel_line); 
+      fflush (stdout);
+    }
+
+  if (bcel_len <= max)
+    {
+      strncpy (buf, bcel_line, bcel_len);
+      *result = bcel_len;
+      bcel_len = 0;
+    }
+  else
+    {
+      strncpy (buf, bcel_line, max);
+      *result = max;
+      bcel_line += max;
+      bcel_len -= max;
+    }
+}
+#endif
+
+#ifdef READLINE
+/* Support for the readline and history libraries.  This allows
+   nicer input on the interactive part of input. */
+
+/* Have input call the following function. */
+#undef  YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+               rl_input((char *)buf, &result, max_size)
+
+/* Variables to help interface readline with bc. */
+static char *rl_line = (char *)NULL;
+static char *rl_start = (char *)NULL;
+static int   rl_len = 0;
+
+/* Definitions for readline access. */
+extern FILE *rl_instream;
+
+/* rl_input puts upto MAX characters into BUF with the number put in
+   BUF placed in *RESULT.  If the yy input file is the same as
+   rl_instream (stdin), use readline.  Otherwise, just read it.
+*/
+
+static void
+rl_input (buf, result, max)
+       char *buf;
+       int  *result;
+       int   max;
+{
+  if (yyin != rl_instream)
+    {
+      while ( (*result = read( fileno(yyin), buf, max )) < 0 )
+        if (errno != EINTR)
+         {
+           yyerror( "read() in flex scanner failed" );
+           exit (1);
+         }
+      return;
+    }
+
+  /* Do we need a new string? */
+  if (rl_len == 0)
+    {
+      if (rl_start)
+       free(rl_start);
+      rl_start = readline ("");
+      if (rl_start == NULL) {
+       /* end of file */
+       *result = 0;
+       rl_len = 0;
+       return;
+      }
+      rl_line = rl_start;
+      rl_len = strlen (rl_line)+1;
+      if (rl_len != 1)
+       add_history (rl_line); 
+      rl_line[rl_len-1] = '\n';
+      fflush (stdout);
+    }
+
+  if (rl_len <= max)
+    {
+      strncpy (buf, rl_line, rl_len);
+      *result = rl_len;
+      rl_len = 0;
+    }
+  else
+    {
+      strncpy (buf, rl_line, max);
+      *result = max;
+      rl_line += max;
+      rl_len -= max;
+    }
+}
+#endif
+
+#if !defined(READLINE) && !defined(LIBEDIT)
+
+/* MINIX returns from read with < 0 if SIGINT is  encountered.
+   In flex, we can redefine YY_INPUT to the following.  In lex, this
+   does nothing! */
+#undef  YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+       while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
+           if (errno != EINTR) \
+               YY_FATAL_ERROR( "read() in flex scanner failed" );
+#endif
+
+%}
+DIGIT [0-9A-F]
+LETTER [a-z]
+%s slcomment
+%%
+"#"            {
+                 if (!std_only)
+                   BEGIN(slcomment);
+                 else
+                   yyerror ("illegal character: #");
+               }
+<slcomment>[^\n]* { BEGIN(INITIAL); }
+<slcomment>"\n" { line_no++; BEGIN(INITIAL); return(ENDOFLINE); }
+define return(Define);
+break  return(Break);
+quit   return(Quit);
+length return(Length);
+return return(Return);
+for    return(For);
+if     return(If);
+while  return(While);
+sqrt   return(Sqrt);
+scale  return(Scale);
+ibase  return(Ibase);
+obase  return(Obase);
+auto   return(Auto);
+else   return(Else);
+read   return(Read);
+random return(Random);
+halt   return(Halt);
+last   return(Last);
+void   return(Void); 
+history {
+#if defined(READLINE) || defined(LIBEDIT)
+         return(HistoryVar);
+#else
+         yylval.s_value = strcopyof(yytext); return(NAME);
+#endif
+       }
+
+warranty return(Warranty);
+continue return(Continue);
+print  return(Print);
+limits return(Limits);
+"." {
+#ifdef DOT_IS_LAST
+       return(Last);
+#else
+       yyerror ("illegal character: %s",yytext);
+#endif
+    }
+"+"|"-"|";"|"("|")"|"{"|"}"|"["|"]"|","|"^" { yylval.c_value = yytext[0]; 
+                                             return((int)yytext[0]); }
+&& { return(AND); }
+\|\| { return(OR); }
+"!" { return(NOT); }
+"*"|"/"|"%"|"&" { yylval.c_value = yytext[0]; return((int)yytext[0]); }
+"="|\+=|-=|\*=|\/=|%=|\^=  { yylval.c_value = yytext[0]; return(ASSIGN_OP); }
+=\+|=-|=\*|=\/|=%|=\^  { 
+#ifdef OLD_EQ_OP
+                        char warn_save;
+                        warn_save = warn_not_std;
+                        warn_not_std = TRUE;
+                        warn ("Old fashioned =<op>");
+                        warn_not_std = warn_save;
+                        yylval.c_value = yytext[1];
+#else
+                        yylval.c_value = '=';
+                        yyless (1);
+#endif
+                        return(ASSIGN_OP);
+                      }
+==|\<=|\>=|\!=|"<"|">" { yylval.s_value = strcopyof(yytext); return(REL_OP); }
+\+\+|-- { yylval.c_value = yytext[0]; return(INCR_DECR); }
+"\n" { line_no++; return(ENDOFLINE); }
+\\\n {  line_no++;  /* ignore a "quoted" newline */ }
+[ \t]+  { /* ignore spaces and tabs */ }
+"/*"  {
+       int c;
+
+       for (;;)
+         {
+           while ( ((c=input()) != '*') && (c != EOF)) 
+             /* eat it */
+             if (c == '\n') line_no++;
+           if (c == '*')
+             {
+               while ( (c=input()) == '*') /* eat it*/;
+               if (c == '/') break; /* at end of comment */
+               if (c == '\n') line_no++;
+             }
+           if (c == EOF)
+             {
+               fprintf (stderr,"EOF encountered in a comment.\n");
+               break;
+             }
+         }
+      }
+[a-z][a-z0-9_]* { yylval.s_value = strcopyof(yytext); return(NAME); }
+\"[^\"]*\"  {
+             const char *look;
+             int count = 0;
+             yylval.s_value = strcopyof(yytext);
+             for (look = yytext; *look != 0; look++)
+               {
+                 if (*look == '\n') line_no++;
+                 if (*look == '"')  count++;
+               }
+             if (count != 2) yyerror ("NUL character in string.");
+             return(STRING);
+           }
+{DIGIT}({DIGIT}|\\\n)*("."({DIGIT}|\\\n)*)?|"."(\\\n)*{DIGIT}({DIGIT}|\\\n)* {
+             char *src, *dst;
+             int len;
+             /* remove a trailing decimal point. */
+             len = strlen(yytext);
+             if (yytext[len-1] == '.')
+               yytext[len-1] = 0;
+             /* remove leading zeros. */
+             src = yytext;
+             dst = yytext;
+             while (*src == '0') src++;
+             if (*src == 0) src--;
+             /* Copy strings removing the newlines. */
+             while (*src != 0)
+               {
+                 if (*src == '\\')
+                   {
+                     src++; src++;
+                     line_no++;
+                   }
+                 else
+                   *dst++ = *src++;
+               }
+             *dst = 0;
+             yylval.s_value = strcopyof(yytext); 
+             return(NUMBER);
+           }
+.       {
+         if (yytext[0] < ' ')
+           yyerror ("illegal character: ^%c",yytext[0] + '@');
+         else
+           if (yytext[0] > '~')
+             yyerror ("illegal character: \\%03o", (int) yytext[0]);
+           else
+             yyerror ("illegal character: %s",yytext);
+       }
+%%
+
+
+
+/* This is the way to get multiple files input into lex. */
+
+int
+yywrap()
+{
+  if (!open_new_file ()) return (1);   /* EOF on standard in. */
+  return (0);                          /* We have more input. */
+}
diff --git a/bc/storage.c b/bc/storage.c
new file mode 100644 (file)
index 0000000..699729a
--- /dev/null
@@ -0,0 +1,1073 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* storage.c:  Code and data storage manipulations.  This includes labels. */
+
+#include "bcdefs.h"
+#include "proto.h"
+
+
+/* Initialize the storage at the beginning of the run. */
+
+void
+init_storage ()
+{
+
+  /* Functions: we start with none and ask for more. */
+  f_count = 0;
+  more_functions ();
+  f_names[0] = (char *)"(main)";
+
+  /* Variables. */
+  v_count = 0;
+  more_variables ();
+  
+  /* Arrays. */
+  a_count = 0;
+  more_arrays ();
+
+  /* Other things... */
+  ex_stack = NULL;
+  fn_stack = NULL;
+  i_base = 10;
+  o_base = 10;
+  scale  = 0;
+#if defined(READLINE) || defined(LIBEDIT)
+  n_history = -1;      
+#endif
+  c_code = FALSE;
+  bc_init_numbers();
+}
+
+/* Three functions for increasing the number of functions, variables, or
+   arrays that are needed.  This adds another 32 of the requested object. */
+
+void
+more_functions (VOID)
+{
+  int old_count;
+  int indx;
+  bc_function *old_f;
+  bc_function *f;
+  char **old_names;
+
+  /* Save old information. */
+  old_count = f_count;
+  old_f = functions;
+  old_names = f_names;
+
+  /* Add a fixed amount and allocate new space. */
+  f_count += STORE_INCR;
+  functions = (bc_function *) bc_malloc (f_count*sizeof (bc_function));
+  f_names = (char **) bc_malloc (f_count*sizeof (char *));
+
+  /* Copy old ones. */
+  for (indx = 0; indx < old_count; indx++)
+    {
+      functions[indx] = old_f[indx];
+      f_names[indx] = old_names[indx];
+    }
+
+  /* Initialize the new ones. */
+  for (; indx < f_count; indx++)
+    {
+      f = &functions[indx];
+      f->f_defined = FALSE;
+      f->f_body = (char *) bc_malloc (BC_START_SIZE);
+      f->f_body_size = BC_START_SIZE;
+      f->f_code_size = 0;
+      f->f_label = NULL;
+      f->f_autos = NULL;
+      f->f_params = NULL;
+    }
+
+  /* Free the old elements. */
+  if (old_count != 0)
+    {
+      free (old_f);
+      free (old_names);
+    }
+}
+
+void
+more_variables ()
+{
+  int indx;
+  int old_count;
+  bc_var **old_var;
+  char **old_names;
+
+  /* Save the old values. */
+  old_count = v_count;
+  old_var = variables;
+  old_names = v_names;
+
+  /* Increment by a fixed amount and allocate. */
+  v_count += STORE_INCR;
+  variables = (bc_var **) bc_malloc (v_count*sizeof(bc_var *));
+  v_names = (char **) bc_malloc (v_count*sizeof(char *));
+
+  /* Copy the old variables. */
+  for (indx = 3; indx < old_count; indx++)
+    {
+      variables[indx] = old_var[indx];
+      v_names[indx] = old_names[indx];
+    }
+
+  /* Initialize the new elements. */
+  for (; indx < v_count; indx++)
+    variables[indx] = NULL;
+
+  /* Free the old elements. */
+  if (old_count != 0)
+    {
+      free (old_var);
+      free (old_names);
+    }
+}
+
+void
+more_arrays ()
+{
+  int indx;
+  int old_count;
+  bc_var_array **old_ary;
+  char **old_names;
+
+  /* Save the old values. */
+  old_count = a_count;
+  old_ary = arrays;
+  old_names = a_names;
+
+  /* Increment by a fixed amount and allocate. */
+  a_count += STORE_INCR;
+  arrays = (bc_var_array **) bc_malloc (a_count*sizeof(bc_var_array *));
+  a_names = (char **) bc_malloc (a_count*sizeof(char *));
+
+  /* Copy the old arrays. */
+  for (indx = 1; indx < old_count; indx++)
+    {
+      arrays[indx] = old_ary[indx];
+      a_names[indx] = old_names[indx];
+    }
+
+
+  /* Initialize the new elements. */
+  for (; indx < v_count; indx++)
+    arrays[indx] = NULL;
+
+  /* Free the old elements. */
+  if (old_count != 0)
+    {
+      free (old_ary);
+      free (old_names);
+    }
+}
+
+
+/* clear_func clears out function FUNC and makes it ready to redefine. */
+
+void
+clear_func (func)
+     int func;
+{
+  bc_function *f;
+  bc_label_group *lg;
+
+  /* Set the pointer to the function. */
+  f = &functions[func];
+  f->f_defined = FALSE;
+  /* XXX restore f_body to initial size??? */
+  f->f_code_size = 0;
+  if (f->f_autos != NULL)
+    {
+      free_args (f->f_autos);
+      f->f_autos = NULL;
+    }
+  if (f->f_params != NULL)
+    {
+      free_args (f->f_params);
+      f->f_params = NULL;
+    }
+  while (f->f_label != NULL)
+    {
+      lg = f->f_label->l_next;
+      free (f->f_label);
+      f->f_label = lg;
+    }
+}
+
+
+/*  Pop the function execution stack and return the top. */
+
+int
+fpop()
+{
+  fstack_rec *temp;
+  int retval;
+  
+  if (fn_stack != NULL)
+    {
+      temp = fn_stack;
+      fn_stack = temp->s_next;
+      retval = temp->s_val;
+      free (temp);
+    }
+  else
+    {
+      retval = 0;
+      rt_error ("function stack underflow, contact maintainer.");
+    }
+  return (retval);
+}
+
+
+/* Push VAL on to the function stack. */
+
+void
+fpush (val)
+     int val;
+{
+  fstack_rec *temp;
+  
+  temp = (fstack_rec *) bc_malloc (sizeof (fstack_rec));
+  temp->s_next = fn_stack;
+  temp->s_val = val;
+  fn_stack = temp;
+}
+
+
+/* Pop and discard the top element of the regular execution stack. */
+
+void
+pop ()
+{
+  estack_rec *temp;
+  
+  if (ex_stack != NULL)
+    {
+      temp = ex_stack;
+      ex_stack = temp->s_next;
+      bc_free_num (&temp->s_num);
+      free (temp);
+    }
+}
+
+
+/* Push a copy of NUM on to the regular execution stack. */
+
+void
+push_copy (num)
+     bc_num num;
+{
+  estack_rec *temp;
+
+  temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
+  temp->s_num = bc_copy_num (num);
+  temp->s_next = ex_stack;
+  ex_stack = temp;
+}
+
+
+/* Push NUM on to the regular execution stack.  Do NOT push a copy. */
+
+void
+push_num (num)
+     bc_num num;
+{
+  estack_rec *temp;
+
+  temp = (estack_rec *) bc_malloc (sizeof (estack_rec));
+  temp->s_num = num;
+  temp->s_next = ex_stack;
+  ex_stack = temp;
+}
+
+
+/* Make sure the ex_stack has at least DEPTH elements on it.
+   Return TRUE if it has at least DEPTH elements, otherwise
+   return FALSE. */
+
+char
+check_stack (depth)
+     int depth;
+{
+  estack_rec *temp;
+
+  temp = ex_stack;
+  while ((temp != NULL) && (depth > 0))
+    {
+      temp = temp->s_next;
+      depth--;
+    }
+  if (depth > 0)
+    {
+      rt_error ("Stack error.");
+      return FALSE;
+    }
+  return TRUE;
+}
+
+
+/* The following routines manipulate simple variables and
+   array variables. */
+
+/* get_var returns a pointer to the variable VAR_NAME.  If one does not
+   exist, one is created. */
+
+bc_var *
+get_var (var_name)
+     int var_name;
+{
+  bc_var *var_ptr;
+
+  var_ptr = variables[var_name];
+  if (var_ptr == NULL)
+    {
+      var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var));
+      bc_init_num (&var_ptr->v_value);
+    }
+  return var_ptr;
+}
+
+
+/* get_array_num returns the address of the bc_num in the array
+   structure.  If more structure is requried to get to the index,
+   this routine does the work to create that structure. VAR_INDEX
+   is a zero based index into the arrays storage array. INDEX is
+   the index into the bc array. */
+
+bc_num *
+get_array_num (var_index, idx)
+     int var_index;
+     long  idx;
+{
+  bc_var_array *ary_ptr;
+  bc_array *a_var;
+  bc_array_node *temp;
+  int log, ix, ix1;
+  int sub [NODE_DEPTH];
+
+  /* Get the array entry. */
+  ary_ptr = arrays[var_index];
+  if (ary_ptr == NULL)
+    {
+      ary_ptr = arrays[var_index] =
+       (bc_var_array *) bc_malloc (sizeof (bc_var_array));
+      ary_ptr->a_value = NULL;
+      ary_ptr->a_next = NULL;
+      ary_ptr->a_param = FALSE;
+    }
+
+  a_var = ary_ptr->a_value;
+  if (a_var == NULL) {
+    a_var = ary_ptr->a_value = (bc_array *) bc_malloc (sizeof (bc_array));
+    a_var->a_tree = NULL;
+    a_var->a_depth = 0;
+  }
+
+  /* Get the index variable. */
+  sub[0] = idx & NODE_MASK;
+  ix = idx >> NODE_SHIFT;
+  log = 1;
+  while (ix > 0 || log < a_var->a_depth)
+    {
+      sub[log] = ix & NODE_MASK;
+      ix >>= NODE_SHIFT;
+      log++;
+    }
+  
+  /* Build any tree that is necessary. */
+  while (log > a_var->a_depth)
+    {
+      temp = (bc_array_node *) bc_malloc (sizeof(bc_array_node));
+      if (a_var->a_depth != 0)
+       {
+         temp->n_items.n_down[0] = a_var->a_tree;
+         for (ix=1; ix < NODE_SIZE; ix++)
+           temp->n_items.n_down[ix] = NULL;
+       }
+      else
+       {
+         for (ix=0; ix < NODE_SIZE; ix++)
+           temp->n_items.n_num[ix] = bc_copy_num(_zero_);
+       }
+      a_var->a_tree = temp;
+      a_var->a_depth++;
+    }
+  
+  /* Find the indexed variable. */
+  temp = a_var->a_tree;
+  while ( log-- > 1)
+    {
+      ix1 = sub[log];
+      if (temp->n_items.n_down[ix1] == NULL)
+       {
+         temp->n_items.n_down[ix1] =
+           (bc_array_node *) bc_malloc (sizeof(bc_array_node));
+         temp = temp->n_items.n_down[ix1];
+         if (log > 1)
+           for (ix=0; ix < NODE_SIZE; ix++)
+             temp->n_items.n_down[ix] = NULL;
+         else
+           for (ix=0; ix < NODE_SIZE; ix++)
+             temp->n_items.n_num[ix] = bc_copy_num(_zero_);
+       }
+      else
+       temp = temp->n_items.n_down[ix1];
+    }
+  
+  /* Return the address of the indexed variable. */
+  return &(temp->n_items.n_num[sub[0]]);
+}
+
+
+/* Store the top of the execution stack into VAR_NAME.  
+   This includes the special variables ibase, obase, and scale. */
+
+void
+store_var (var_name)
+     int var_name;
+{
+  bc_var *var_ptr;
+  long temp;
+  char toobig;
+
+  if (var_name > 3)
+    {
+      /* It is a simple variable. */
+      var_ptr = get_var (var_name);
+      if (var_ptr != NULL)
+       {
+         bc_free_num(&var_ptr->v_value);
+         var_ptr->v_value = bc_copy_num (ex_stack->s_num);
+       }
+    }
+  else
+    {
+      /* It is a special variable... */
+      toobig = FALSE;
+      temp = 0;
+      if (bc_is_neg (ex_stack->s_num))
+       {
+         switch (var_name)
+           {
+           case 0:
+             rt_warn ("negative ibase, set to 2");
+             temp = 2;
+             break;
+           case 1:
+             rt_warn ("negative obase, set to 2");
+             temp = 2;
+             break;
+           case 2:
+             rt_warn ("negative scale, set to 0");
+             temp = 0;
+             break;
+#if defined(READLINE) || defined(LIBEDIT)
+           case 3:
+             temp = -1;
+             break;
+#endif
+           }
+       }
+      else
+       {
+         temp = bc_num2long (ex_stack->s_num);
+         if (!bc_is_zero (ex_stack->s_num) && temp == 0)
+           toobig = TRUE;
+       }
+      switch (var_name)
+       {
+       case 0:
+         if (temp < 2 && !toobig)
+           {
+             i_base = 2;
+             rt_warn ("ibase too small, set to 2");
+           }
+         else
+           if (temp > 16 || toobig)
+             {
+               i_base = 16;
+               rt_warn ("ibase too large, set to 16");
+             }
+           else
+             i_base = (int) temp;
+         break;
+
+       case 1:
+         if (temp < 2 && !toobig)
+           {
+             o_base = 2;
+             rt_warn ("obase too small, set to 2");
+           }
+         else
+           if (temp > BC_BASE_MAX || toobig)
+             {
+               o_base = BC_BASE_MAX;
+               rt_warn ("obase too large, set to %d", BC_BASE_MAX);
+             }
+           else
+             o_base = (int) temp;
+         break;
+
+       case 2:
+         /*  WARNING:  The following if statement may generate a compiler
+             warning if INT_MAX == LONG_MAX.  This is NOT a problem. */
+         if (temp > BC_SCALE_MAX || toobig )
+           {
+             scale = BC_SCALE_MAX;
+             rt_warn ("scale too large, set to %d", BC_SCALE_MAX);
+           }
+         else
+           scale = (int) temp;
+         break;
+
+#if defined(READLINE) || defined(LIBEDIT)
+       case 3:
+         if (toobig)
+           {
+             temp = -1;
+             rt_warn ("history too large, set to unlimited");
+             UNLIMIT_HISTORY;
+           }
+         else
+           {
+             n_history = temp;
+             if (temp < 0)
+               UNLIMIT_HISTORY;
+             else
+               HISTORY_SIZE(n_history);
+           }
+#endif
+       }
+    }
+}
+
+
+/* Store the top of the execution stack into array VAR_NAME. 
+   VAR_NAME is the name of an array, and the next to the top
+   of stack for the index into the array. */
+
+void
+store_array (var_name)
+     int var_name;
+{
+  bc_num *num_ptr;
+  long idx;
+
+  if (!check_stack(2)) return;
+  idx = bc_num2long (ex_stack->s_next->s_num);
+  if (idx < 0 || idx > BC_DIM_MAX ||
+      (idx == 0 && !bc_is_zero(ex_stack->s_next->s_num))) 
+    rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
+  else
+    {
+      num_ptr = get_array_num (var_name, idx);
+      if (num_ptr != NULL)
+       {
+         bc_free_num (num_ptr);
+         *num_ptr = bc_copy_num (ex_stack->s_num);
+         bc_free_num (&ex_stack->s_next->s_num);
+         ex_stack->s_next->s_num = ex_stack->s_num;
+         bc_init_num (&ex_stack->s_num);
+         pop();
+       }
+    }
+}
+
+
+/*  Load a copy of VAR_NAME on to the execution stack.  This includes
+    the special variables ibase, obase and scale.  */
+
+void
+load_var (var_name)
+     int var_name;
+{
+  bc_var *var_ptr;
+
+  switch (var_name)
+    {
+
+    case 0:
+      /* Special variable ibase. */
+      push_copy (_zero_);
+      bc_int2num (&ex_stack->s_num, i_base);
+      break;
+
+    case 1:
+      /* Special variable obase. */
+      push_copy (_zero_);
+      bc_int2num (&ex_stack->s_num, o_base);
+      break;
+
+    case 2:
+      /* Special variable scale. */
+      push_copy (_zero_);
+      bc_int2num (&ex_stack->s_num, scale);
+      break;
+
+#if defined(READLINE) || defined(LIBEDIT)
+    case 3:
+      /* Special variable history. */
+      push_copy (_zero_);
+      bc_int2num (&ex_stack->s_num, n_history);
+      break;
+#endif
+
+    default:
+      /* It is a simple variable. */
+      var_ptr = variables[var_name];
+      if (var_ptr != NULL)
+       push_copy (var_ptr->v_value);
+      else
+       push_copy (_zero_);
+    }
+}
+
+
+/*  Load a copy of VAR_NAME on to the execution stack.  This includes
+    the special variables ibase, obase and scale.  */
+
+void
+load_array (var_name)
+     int var_name;
+{
+  bc_num *num_ptr;
+  long   idx;
+
+  if (!check_stack(1)) return;
+  idx = bc_num2long (ex_stack->s_num);
+  if (idx < 0 || idx > BC_DIM_MAX ||
+     (idx == 0 && !bc_is_zero(ex_stack->s_num))) 
+    rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
+  else
+    {
+      num_ptr = get_array_num (var_name, idx);
+      if (num_ptr != NULL)
+       {
+         pop();
+         push_copy (*num_ptr);
+       }
+    }
+}
+
+
+/* Decrement VAR_NAME by one.  This includes the special variables
+   ibase, obase, and scale. */
+
+void
+decr_var (var_name)
+     int var_name;
+{
+  bc_var *var_ptr;
+
+  switch (var_name)
+    {
+
+    case 0: /* ibase */
+      if (i_base > 2)
+       i_base--;
+      else
+       rt_warn ("ibase too small in --");
+      break;
+      
+    case 1: /* obase */
+      if (o_base > 2)
+       o_base--;
+      else
+       rt_warn ("obase too small in --");
+      break;
+
+    case 2: /* scale */
+      if (scale > 0)
+       scale--;
+      else
+       rt_warn ("scale can not be negative in -- ");
+      break;
+
+#if defined(READLINE) || defined(LIBEDIT)
+    case 3: /* history */
+      n_history--;
+      if (n_history >= 0)
+       HISTORY_SIZE(n_history);
+      else
+       {
+         n_history = -1;
+         rt_warn ("history is negative, set to unlimited");
+         UNLIMIT_HISTORY;
+       }
+#endif
+
+    default: /* It is a simple variable. */
+      var_ptr = get_var (var_name);
+      if (var_ptr != NULL)
+       bc_sub (var_ptr->v_value,_one_,&var_ptr->v_value, 0);
+    }
+}
+
+
+/* Decrement VAR_NAME by one.  VAR_NAME is an array, and the top of
+   the execution stack is the index and it is popped off the stack. */
+
+void
+decr_array (var_name)
+     int var_name;
+{
+  bc_num *num_ptr;
+  long   idx;
+
+  /* It is an array variable. */
+  if (!check_stack (1)) return;
+  idx = bc_num2long (ex_stack->s_num);
+  if (idx < 0 || idx > BC_DIM_MAX ||
+     (idx == 0 && !bc_is_zero (ex_stack->s_num))) 
+    rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
+  else
+    {
+      num_ptr = get_array_num (var_name, idx);
+      if (num_ptr != NULL)
+       {
+         pop ();
+         bc_sub (*num_ptr, _one_, num_ptr, 0);
+       }
+    }
+}
+
+
+/* Increment VAR_NAME by one.  This includes the special variables
+   ibase, obase, and scale. */
+
+void
+incr_var (var_name)
+     int var_name;
+{
+  bc_var *var_ptr;
+
+  switch (var_name)
+    {
+
+    case 0: /* ibase */
+      if (i_base < 16)
+       i_base++;
+      else
+       rt_warn ("ibase too big in ++");
+      break;
+
+    case 1: /* obase */
+      if (o_base < BC_BASE_MAX)
+       o_base++;
+      else
+       rt_warn ("obase too big in ++");
+      break;
+
+    case 2:
+      if (scale < BC_SCALE_MAX)
+       scale++;
+      else
+       rt_warn ("Scale too big in ++");
+      break;
+
+#if defined(READLINE) || defined(LIBEDIT)
+    case 3: /* history */
+      n_history++;
+      if (n_history > 0)
+       HISTORY_SIZE(n_history);
+      else
+       {
+         n_history = -1;
+         rt_warn ("history set to unlimited");
+         UNLIMIT_HISTORY;
+       }
+#endif
+
+    default:  /* It is a simple variable. */
+      var_ptr = get_var (var_name);
+      if (var_ptr != NULL)
+       bc_add (var_ptr->v_value, _one_, &var_ptr->v_value, 0);
+
+    }
+}
+
+
+/* Increment VAR_NAME by one.  VAR_NAME is an array and top of
+   execution stack is the index and is popped off the stack. */
+
+void
+incr_array (var_name)
+     int var_name;
+{
+  bc_num *num_ptr;
+  long   idx;
+
+  if (!check_stack (1)) return;
+  idx = bc_num2long (ex_stack->s_num);
+  if (idx < 0 || idx > BC_DIM_MAX ||
+      (idx == 0 && !bc_is_zero (ex_stack->s_num))) 
+    rt_error ("Array %s subscript out of bounds.", a_names[var_name]);
+  else
+    {
+      num_ptr = get_array_num (var_name, idx);
+      if (num_ptr != NULL)
+       {
+         pop ();
+         bc_add (*num_ptr, _one_, num_ptr, 0);
+       }
+    }
+}
+
+
+/* Routines for processing autos variables and parameters. */
+
+/* NAME is an auto variable that needs to be pushed on its stack. */
+
+void
+auto_var (name)
+     int name;
+{
+  bc_var *v_temp;
+  bc_var_array *a_temp;
+  int ix;
+
+  if (name > 0)
+    {
+      /* A simple variable. */
+      ix = name;
+      v_temp = (bc_var *) bc_malloc (sizeof (bc_var));
+      v_temp->v_next = variables[ix];
+      bc_init_num (&v_temp->v_value);
+      variables[ix] = v_temp;
+    }
+  else
+    {
+      /* An array variable. */
+      ix = -name;
+      a_temp = (bc_var_array *) bc_malloc (sizeof (bc_var_array));
+      a_temp->a_next = arrays[ix];
+      a_temp->a_value = NULL;
+      a_temp->a_param = FALSE;
+      arrays[ix] = a_temp;
+    } 
+}
+
+
+/* Free_a_tree frees everything associated with an array variable tree.
+   This is used when popping an array variable off its auto stack.  */
+
+void
+free_a_tree ( root, depth )
+     bc_array_node *root;
+     int depth;
+{
+  int ix;
+
+  if (root != NULL)
+    {
+      if (depth > 1)
+       for (ix = 0; ix < NODE_SIZE; ix++)
+         free_a_tree (root->n_items.n_down[ix], depth-1);
+      else
+       for (ix = 0; ix < NODE_SIZE; ix++)
+         bc_free_num ( &(root->n_items.n_num[ix]));
+      free (root);
+    }
+}
+
+
+/* LIST is an NULL terminated list of varible names that need to be
+   popped off their auto stacks. */
+
+void
+pop_vars (list)
+     arg_list *list;
+{
+  bc_var *v_temp;
+  bc_var_array *a_temp;
+  int    ix;
+
+  while (list != NULL)
+    {
+      ix = list->av_name;
+      if (ix > 0)
+       {
+         /* A simple variable. */
+         v_temp = variables[ix];
+         if (v_temp != NULL)
+           {
+             variables[ix] = v_temp->v_next;
+             bc_free_num (&v_temp->v_value);
+             free (v_temp);
+           }
+       }
+      else
+       {
+         /* An array variable. */
+         ix = -ix;
+         a_temp = arrays[ix];
+         if (a_temp != NULL)
+           {
+             arrays[ix] = a_temp->a_next;
+             if (!a_temp->a_param && a_temp->a_value != NULL)
+               {
+                 free_a_tree (a_temp->a_value->a_tree,
+                              a_temp->a_value->a_depth);
+                 free (a_temp->a_value);
+               }
+             free (a_temp);
+           }
+       } 
+      list = list->next;
+    }
+}
+
+/* COPY_NODE: Copies an array node for a call by value parameter. */
+bc_array_node *
+copy_tree (ary_node, depth)
+     bc_array_node *ary_node;
+     int depth;
+{
+  bc_array_node *res = (bc_array_node *) bc_malloc (sizeof(bc_array_node));
+  int i;
+
+  if (depth > 1)
+    for (i=0; i<NODE_SIZE; i++)
+      if (ary_node->n_items.n_down[i] != NULL)
+       res->n_items.n_down[i] =
+         copy_tree (ary_node->n_items.n_down[i], depth - 1);
+      else
+       res->n_items.n_down[i] = NULL;
+  else
+    for (i=0; i<NODE_SIZE; i++)
+      if (ary_node->n_items.n_num[i] != NULL)
+       res->n_items.n_num[i] = bc_copy_num (ary_node->n_items.n_num[i]);
+      else
+       res->n_items.n_num[i] = NULL;
+  return res;
+}
+
+/* COPY_ARRAY: Copies an array for a call by value array parameter. 
+   ARY is the pointer to the bc_array structure. */
+
+bc_array *
+copy_array (ary)
+     bc_array *ary;
+{
+  bc_array *res = (bc_array *) bc_malloc (sizeof(bc_array));
+  res->a_depth = ary->a_depth;
+  res->a_tree = copy_tree (ary->a_tree, ary->a_depth);
+  return (res);
+}
+
+
+/* A call is being made to FUNC.  The call types are at PC.  Process
+   the parameters by doing an auto on the parameter variable and then
+   store the value at the new variable or put a pointer the the array
+   variable. */
+
+void
+process_params (progctr, func)
+     program_counter *progctr;
+     int func;
+{
+  char ch;
+  arg_list *params;
+  int ix, ix1;
+  bc_var *v_temp;
+  bc_var_array *a_src, *a_dest;
+  bc_num *n_temp;
+  
+  /* Get the parameter names from the function. */
+  params = functions[func].f_params;
+
+  while ((ch = byte(progctr)) != ':')
+    {
+      if (params != NULL)
+       {
+         if ((ch == '0') && params->av_name > 0)
+           {
+             /* A simple variable. */
+             ix = params->av_name;
+             v_temp = (bc_var *) bc_malloc (sizeof(bc_var));
+             v_temp->v_next = variables[ix];
+             v_temp->v_value = ex_stack->s_num;
+             bc_init_num (&ex_stack->s_num);
+             variables[ix] = v_temp;
+           }
+         else
+           if ((ch == '1') && (params->av_name < 0))
+             {
+               /* The variables is an array variable. */
+       
+               /* Compute source index and make sure some structure exists. */
+               ix = (int) bc_num2long (ex_stack->s_num);
+               n_temp = get_array_num (ix, 0);    
+       
+               /* Push a new array and Compute Destination index */
+               auto_var (params->av_name);  
+               ix1 = -params->av_name;
+
+               /* Set up the correct pointers in the structure. */
+               if (ix == ix1) 
+                 a_src = arrays[ix]->a_next;
+               else
+                 a_src = arrays[ix];
+               a_dest = arrays[ix1];
+               if (params->arg_is_var)
+                 {
+                   a_dest->a_param = TRUE;
+                   a_dest->a_value = a_src->a_value;
+                 }
+               else
+                 {
+                   a_dest->a_param = FALSE;
+                   a_dest->a_value = copy_array (a_src->a_value);
+                 }
+             }
+           else
+             {
+               if (params->av_name < 0)
+                 rt_error ("Parameter type mismatch parameter %s.",
+                           a_names[-params->av_name]);
+               else
+                 rt_error ("Parameter type mismatch, parameter %s.",
+                           v_names[params->av_name]);
+               params++;
+             }
+         pop ();
+       }
+      else
+       {
+           rt_error ("Parameter number mismatch");
+           return;
+       }
+      params = params->next;
+    }
+  if (params != NULL) 
+    rt_error ("Parameter number mismatch");
+}
diff --git a/bc/util.c b/bc/util.c
new file mode 100644 (file)
index 0000000..30beaf9
--- /dev/null
+++ b/bc/util.c
@@ -0,0 +1,846 @@
+/*  This file is part of GNU bc.
+
+    Copyright (C) 1991-1994, 1997, 2006 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+      The Free Software Foundation, Inc.
+      Foundation, Inc.  51 Franklin Street, Fifth Floor,
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+/* util.c: Utility routines for bc. */
+
+#include "bcdefs.h"
+#ifndef VARARGS
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "proto.h"
+
+
+/* strcopyof mallocs new memory and copies a string to to the new
+   memory. */
+
+char *
+strcopyof (str)
+     const char *str;
+{
+  char *temp;
+
+  temp = (char *) bc_malloc (strlen (str)+1);
+  return (strcpy (temp,str));
+}
+
+
+/* nextarg adds another value to the list of arguments. */
+
+arg_list *
+nextarg (args, val, is_var)
+     arg_list *args;
+     int val;
+     int is_var;
+{ arg_list *temp;
+
+  temp = (arg_list *) bc_malloc (sizeof (arg_list));
+  temp->av_name = val;
+  temp->arg_is_var = is_var;
+  temp->next = args;
+  return (temp);
+}
+
+
+/* For generate, we must produce a string in the form
+    "val,val,...,val".  We also need a couple of static variables
+   for retaining old generated strings.  It also uses a recursive
+   function that builds the string. */
+
+static char *arglist1 = NULL, *arglist2 = NULL;
+
+
+/* make_arg_str does the actual construction of the argument string.
+   ARGS is the pointer to the list and LEN is the maximum number of
+   characters needed.  1 char is the minimum needed. 
+ */
+
+_PROTOTYPE (static char *make_arg_str, (arg_list *args, int len));
+
+static char *
+make_arg_str (args, len)
+      arg_list *args;
+      int len;
+{
+  char *temp;
+  char sval[20];
+
+  /* Recursive call. */
+  if (args != NULL)
+    temp = make_arg_str (args->next, len+12);
+  else
+    {
+      temp = (char *) bc_malloc (len);
+      *temp = 0;
+      return temp;
+    }
+
+  /* Add the current number to the end of the string. */
+  if (args->arg_is_var)
+    if (len != 1) 
+      sprintf (sval, "*%d,", args->av_name);
+    else
+      sprintf (sval, "*%d", args->av_name);
+  else
+    if (len != 1) 
+      sprintf (sval, "%d,", args->av_name);
+    else
+      sprintf (sval, "%d", args->av_name);
+  temp = strcat (temp, sval);
+  return (temp);
+}
+
+char *
+arg_str (args)
+     arg_list *args;
+{
+  if (arglist2 != NULL) 
+    free (arglist2);
+  arglist2 = arglist1;
+  arglist1 = make_arg_str (args, 1);
+  return (arglist1);
+}
+
+char *
+call_str (args)
+     arg_list *args;
+{
+  arg_list *temp;
+  int       arg_count;
+  int       ix;
+  
+  if (arglist2 != NULL) 
+    free (arglist2);
+  arglist2 = arglist1;
+
+  /* Count the number of args and add the 0's and 1's. */
+  for (temp = args, arg_count = 0; temp != NULL; temp = temp->next)
+    arg_count++;
+  arglist1 = (char *) bc_malloc(arg_count+1);
+  for (temp = args, ix=0; temp != NULL; temp = temp->next)
+    arglist1[ix++] = ( temp->av_name ? '1' : '0');
+  arglist1[ix] = 0;
+      
+  return (arglist1);
+}
+
+/* free_args frees an argument list ARGS. */
+
+void
+free_args (args)
+      arg_list *args;
+{ 
+  arg_list *temp;
+  temp = args;
+  while (temp != NULL)
+    {
+      args = args->next;
+      free (temp);
+      temp = args;
+    }
+}
+
+
+/* Check for valid parameter (PARAMS) and auto (AUTOS) lists.
+   There must be no duplicates any where.  Also, this is where
+   warnings are generated for array parameters. */
+
+void
+check_params ( params, autos )
+     arg_list *params, *autos;
+{
+  arg_list *tmp1, *tmp2;
+
+  /* Check for duplicate parameters. */
+  if (params != NULL)
+    {
+      tmp1 = params;
+      while (tmp1 != NULL)
+       {
+         tmp2 = tmp1->next;
+         while (tmp2 != NULL)
+           {
+             if (tmp2->av_name == tmp1->av_name) 
+               yyerror ("duplicate parameter names");
+             tmp2 = tmp2->next;
+           }
+         if (tmp1->arg_is_var)
+           warn ("Variable array parameter");
+         tmp1 = tmp1->next;
+       }
+    }
+
+  /* Check for duplicate autos. */
+  if (autos != NULL)
+    {
+      tmp1 = autos;
+      while (tmp1 != NULL)
+       {
+         tmp2 = tmp1->next;
+         while (tmp2 != NULL)
+           {
+             if (tmp2->av_name == tmp1->av_name) 
+               yyerror ("duplicate auto variable names");
+             tmp2 = tmp2->next;
+           }
+         if (tmp1->arg_is_var)
+           yyerror ("* not allowed here");
+         tmp1 = tmp1->next;
+       }
+    }
+
+  /* Check for duplicate between parameters and autos. */
+  if ((params != NULL) && (autos != NULL))
+    {
+      tmp1 = params;
+      while (tmp1 != NULL)
+       {
+         tmp2 = autos;
+         while (tmp2 != NULL)
+           {
+             if (tmp2->av_name == tmp1->av_name) 
+               yyerror ("variable in both parameter and auto lists");
+             tmp2 = tmp2->next;
+           }
+         tmp1 = tmp1->next;
+       }
+    }
+}
+
+/* genstr management to avoid buffer overflow. */
+void
+set_genstr_size (size)
+     int size;
+{
+  if (size > genlen) {
+    if (genstr != NULL)
+      free(genstr);
+    genstr = (char *) bc_malloc (size);
+    genlen = size;
+  }
+}
+
+
+/* Initialize the code generator the parser. */
+
+void
+init_gen ()
+{
+  /* Get things ready. */
+  break_label = 0;
+  continue_label = 0;
+  next_label  = 1;
+  out_count = 2;
+  if (compile_only) 
+    printf ("@i");
+  else
+    init_load ();
+  had_error = FALSE;
+  did_gen = FALSE;
+  set_genstr_size (64);
+}
+
+
+/* generate code STR for the machine. */
+
+void
+generate (str)
+      const char *str;
+{
+  did_gen = TRUE;
+  if (compile_only)
+    {
+      printf ("%s",str);
+      out_count += strlen(str);
+      if (out_count > 60)
+       {
+         printf ("\n");
+         out_count = 0;
+       }
+    }
+  else
+    load_code (str);
+}
+
+
+/* Execute the current code as loaded. */
+
+void
+run_code()
+{
+  /* If no compile errors run the current code. */
+  if (!had_error && did_gen)
+    {
+      if (compile_only)
+       {
+         printf ("@r\n"); 
+         out_count = 0;
+       }
+      else
+       execute ();
+    }
+
+  /* Reinitialize the code generation and machine. */
+  if (did_gen)
+    init_gen();
+  else
+    had_error = FALSE;
+}
+
+
+/* Output routines: Write a character CH to the standard output.
+   It keeps track of the number of characters output and may
+   break the output with a "\<cr>".  Always used for numbers. */
+
+void
+out_char (ch)
+     int ch;
+{
+  if (ch == '\n')
+    {
+      out_col = 0;
+      putchar ('\n');
+    }
+  else
+    {
+      out_col++;
+      if (out_col == line_size-1 && line_size != 0)
+       {
+         putchar ('\\');
+         putchar ('\n');
+         out_col = 1;
+       }
+      putchar (ch);
+    }
+}
+
+/* Output routines: Write a character CH to the standard output.
+   It keeps track of the number of characters output and may
+   break the output with a "\<cr>".  This one is for strings.
+   In POSIX bc, strings are not broken across lines. */
+
+void
+out_schar (ch)
+     int ch;
+{
+  if (ch == '\n')
+    {
+      out_col = 0;
+      putchar ('\n');
+    }
+  else
+    {
+      if (!std_only)
+       {
+         out_col++;
+         if (out_col == line_size-1 && line_size != 0)
+           {
+             putchar ('\\');
+             putchar ('\n');
+             out_col = 1;
+           }
+       }
+      putchar (ch);
+    }
+}
+
+
+/* The following are "Symbol Table" routines for the parser. */
+
+/*  find_id returns a pointer to node in TREE that has the correct
+    ID.  If there is no node in TREE with ID, NULL is returned. */
+
+id_rec *
+find_id (tree, id)
+     id_rec *tree;
+     const char   *id;
+{
+  int cmp_result;
+  
+  /* Check for an empty tree. */
+  if (tree == NULL)
+    return NULL;
+
+  /* Recursively search the tree. */
+  cmp_result = strcmp (id, tree->id);
+  if (cmp_result == 0)
+    return tree;  /* This is the item. */
+  else if (cmp_result < 0)
+    return find_id (tree->left, id);
+  else
+    return find_id (tree->right, id);  
+}
+
+
+/* insert_id_rec inserts a NEW_ID rec into the tree whose ROOT is
+   provided.  insert_id_rec returns TRUE if the tree height from
+   ROOT down is increased otherwise it returns FALSE.  This is a
+   recursive balanced binary tree insertion algorithm. */
+
+int insert_id_rec (root, new_id)
+     id_rec **root;
+     id_rec *new_id;
+{
+  id_rec *A, *B;
+
+  /* If root is NULL, this where it is to be inserted. */
+  if (*root == NULL)
+    {
+      *root = new_id;
+      new_id->left = NULL;
+      new_id->right = NULL;
+      new_id->balance = 0;
+      return (TRUE);
+    }
+
+  /* We need to search for a leaf. */
+  if (strcmp (new_id->id, (*root)->id) < 0)
+    {
+      /* Insert it on the left. */
+      if (insert_id_rec (&((*root)->left), new_id))
+       {
+         /* The height increased. */
+         (*root)->balance --;
+         
+         switch ((*root)->balance)
+           {
+           case  0:  /* no height increase. */
+             return (FALSE);
+           case -1:  /* height increase. */
+             return (TRUE);
+           case -2:  /* we need to do a rebalancing act. */
+             A = *root;
+             B = (*root)->left;
+             if (B->balance <= 0)
+               {
+                 /* Single Rotate. */
+                 A->left = B->right;
+                 B->right = A;
+                 *root = B;
+                 A->balance = 0;
+                 B->balance = 0;
+               }
+             else
+               {
+                 /* Double Rotate. */
+                 *root = B->right;
+                 B->right = (*root)->left;
+                 A->left = (*root)->right;
+                 (*root)->left = B;
+                 (*root)->right = A;
+                 switch ((*root)->balance)
+                   {
+                   case -1:
+                     A->balance = 1;
+                     B->balance = 0;
+                     break;
+                   case  0:
+                     A->balance = 0;
+                     B->balance = 0;
+                     break;
+                   case  1:
+                     A->balance = 0;
+                     B->balance = -1;
+                     break;
+                   }
+                 (*root)->balance = 0;
+               }
+           }     
+       } 
+    }
+  else
+    {
+      /* Insert it on the right. */
+      if (insert_id_rec (&((*root)->right), new_id))
+       {
+         /* The height increased. */
+         (*root)->balance ++;
+
+         switch ((*root)->balance)
+           {
+           case 0:  /* no height increase. */
+             return (FALSE);
+           case 1:  /* height increase. */
+             return (TRUE);
+           case 2:  /* we need to do a rebalancing act. */
+             A = *root;
+             B = (*root)->right;
+             if (B->balance >= 0)
+               {
+                 /* Single Rotate. */
+                 A->right = B->left;
+                 B->left = A;
+                 *root = B;
+                 A->balance = 0;
+                 B->balance = 0;
+               }
+             else
+               {
+                 /* Double Rotate. */
+                 *root = B->left;
+                 B->left = (*root)->right;
+                 A->right = (*root)->left;
+                 (*root)->left = A;
+                 (*root)->right = B;
+                 switch ((*root)->balance)
+                   {
+                   case -1:
+                     A->balance = 0;
+                     B->balance = 1;
+                     break;
+                   case  0:
+                     A->balance = 0;
+                     B->balance = 0;
+                     break;
+                   case  1:
+                     A->balance = -1;
+                     B->balance = 0;
+                     break;
+                   }
+                 (*root)->balance = 0;
+               }
+           }     
+       } 
+    }
+  
+  /* If we fall through to here, the tree did not grow in height. */
+  return (FALSE);
+}
+
+
+/* Initialize variables for the symbol table tree. */
+
+void
+init_tree()
+{
+  name_tree  = NULL;
+  next_array = 1;
+  next_func  = 1;
+  /* 0 => ibase, 1 => obase, 2 => scale, 3 => history, 4 => last. */
+  next_var   = 5;
+}
+
+
+/* Lookup routines for symbol table names. */
+
+int
+lookup (name, namekind)
+     char *name;
+     int  namekind;
+{
+  id_rec *id;
+
+  /* Warn about non-standard name. */
+  if (strlen(name) != 1)
+    warn ("multiple letter name - %s", name);
+
+  /* Look for the id. */
+  id = find_id (name_tree, name);
+  if (id == NULL)
+    {
+      /* We need to make a new item. */
+      id = (id_rec *) bc_malloc (sizeof (id_rec));
+      id->id = strcopyof (name);
+      id->a_name = 0;
+      id->f_name = 0;
+      id->v_name = 0;
+      insert_id_rec (&name_tree, id);
+    }
+
+  /* Return the correct value. */
+  switch (namekind)
+    {
+      
+    case ARRAY:
+      /* ARRAY variable numbers are returned as negative numbers. */
+      if (id->a_name != 0)
+       {
+         free (name);
+         return (-id->a_name);
+       }
+      id->a_name = next_array++;
+      if (id->a_name < MAX_STORE)
+       {
+         if (id->a_name >= a_count)
+           more_arrays ();
+         a_names[id->a_name] = name;
+         return (-id->a_name);
+       }
+      yyerror ("Too many array variables");
+      exit (1);
+
+    case FUNCT:
+    case FUNCTDEF:
+      if (id->f_name != 0)
+       {
+         if (namekind != FUNCT)
+           free(name);
+         /* Check to see if we are redefining a math lib function. */ 
+         if (use_math && namekind == FUNCTDEF && id->f_name <= 6)
+           id->f_name = next_func++;
+         return (id->f_name);
+       }
+      id->f_name = next_func++;
+      if (id->f_name < MAX_STORE)
+       {
+         if (id->f_name >= f_count)
+           more_functions ();
+          f_names[id->f_name] = name;
+         return (id->f_name);
+       }
+      yyerror ("Too many functions");
+      exit (1);
+
+    case SIMPLE:
+      if (id->v_name != 0)
+       {
+         free(name);
+         return (id->v_name);
+       }
+      id->v_name = next_var++;
+      if (id->v_name <= MAX_STORE)
+       {
+         if (id->v_name >= v_count)
+           more_variables ();
+          v_names[id->v_name - 1] = name;
+         return (id->v_name);
+       }
+      yyerror ("Too many variables");
+      exit (1);
+    }
+
+  yyerror ("End of util.c/lookup() reached.  Please report this bug.");
+  exit (1);
+  /* not reached */
+}
+
+/* Print out the limits of this program. */
+
+void
+limits()
+{
+  printf ("BC_BASE_MAX     = %d\n",  BC_BASE_MAX);
+  printf ("BC_DIM_MAX      = %ld\n", (long) BC_DIM_MAX);
+  printf ("BC_SCALE_MAX    = %d\n",  BC_SCALE_MAX);
+  printf ("BC_STRING_MAX   = %d\n",  BC_STRING_MAX);
+  printf ("MAX Exponent    = %ld\n", (long) LONG_MAX);
+  printf ("Number of vars  = %ld\n", (long) MAX_STORE);
+#ifdef OLD_EQ_OP
+  printf ("Old assignment operatiors are valid. (=-, =+, ...)\n");
+#endif 
+}
+
+/* bc_malloc will check the return value so all other places do not
+   have to do it!  SIZE is the number of bytes to allocate. */
+
+void *
+bc_malloc (size)
+     int size;
+{
+  void *ptr;
+
+  ptr = (void *) malloc (size);
+  if (ptr == NULL)
+    out_of_memory ();
+
+  return ptr;
+}
+
+
+/* The following routines are error routines for various problems. */
+
+/* Malloc could not get enought memory. */
+
+void
+out_of_memory()
+{
+  fprintf (stderr, "Fatal error: Out of memory for malloc.\n");
+  exit (1);
+}
+
+
+
+/* The standard yyerror routine.  Built with variable number of argumnets. */
+
+#ifndef VARARGS
+#ifdef __STDC__
+void
+yyerror (const char *str, ...)
+#else
+void
+yyerror (str)
+     const char *str;
+#endif
+#else
+void
+yyerror (str, va_alist)
+     const char *str;
+#endif
+{
+  const char *name;
+  va_list args;
+
+#ifndef VARARGS   
+   va_start (args, str);
+#else
+   va_start (args);
+#endif
+  if (is_std_in)
+    name = "(standard_in)";
+  else
+    name = file_name;
+  fprintf (stderr,"%s %d: ",name,line_no);
+  vfprintf (stderr, str, args);
+  fprintf (stderr, "\n");
+  had_error = TRUE;
+  va_end (args);
+}
+
+
+/* The routine to produce warnings about non-standard features
+   found during parsing. */
+
+#ifndef VARARGS
+#ifdef __STDC__
+void 
+warn (const char *mesg, ...)
+#else
+void
+warn (mesg)
+     const char *mesg;
+#endif
+#else
+void
+warn (mesg, va_alist)
+     const char *mesg;
+#endif
+{
+  const char *name;
+  va_list args;
+
+#ifndef VARARGS   
+  va_start (args, mesg);
+#else
+  va_start (args);
+#endif
+  if (std_only)
+    {
+      if (is_std_in)
+       name = "(standard_in)";
+      else
+       name = file_name;
+      fprintf (stderr,"%s %d: Error: ",name,line_no);
+      vfprintf (stderr, mesg, args);
+      fprintf (stderr, "\n");
+      had_error = TRUE;
+    }
+  else
+    if (warn_not_std)
+      {
+       if (is_std_in)
+         name = "(standard_in)";
+       else
+         name = file_name;
+       fprintf (stderr,"%s %d: (Warning) ",name,line_no);
+       vfprintf (stderr, mesg, args);
+       fprintf (stderr, "\n");
+      }
+  va_end (args);
+}
+
+/* Runtime error will  print a message and stop the machine. */
+
+#ifndef VARARGS
+#ifdef __STDC__
+void
+rt_error (const char *mesg, ...)
+#else
+void
+rt_error (mesg)
+     const char *mesg;
+#endif
+#else
+void
+rt_error (mesg, va_alist)
+     const char *mesg;
+#endif
+{
+  va_list args;
+
+  fprintf (stderr, "Runtime error (func=%s, adr=%d): ",
+          f_names[pc.pc_func], pc.pc_addr);
+#ifndef VARARGS   
+  va_start (args, mesg);
+#else
+  va_start (args);
+#endif
+  vfprintf (stderr, mesg, args);
+  va_end (args);
+  
+  fprintf (stderr, "\n");
+  runtime_error = TRUE;
+}
+
+
+/* A runtime warning tells of some action taken by the processor that
+   may change the program execution but was not enough of a problem
+   to stop the execution. */
+
+#ifndef VARARGS
+#ifdef __STDC__
+void
+rt_warn (const char *mesg, ...)
+#else
+void
+rt_warn (mesg)
+     const char *mesg;
+#endif
+#else
+void
+rt_warn (mesg, va_alist)
+     const char *mesg;
+#endif
+{
+  va_list args;
+
+  fprintf (stderr, "Runtime warning (func=%s, adr=%d): ",
+          f_names[pc.pc_func], pc.pc_addr);
+#ifndef VARARGS   
+  va_start (args, mesg);
+#else
+  va_start (args);
+#endif
+  vfprintf (stderr, mesg, args);
+  va_end (args);
+
+  fprintf (stderr, "\n");
+}
diff --git a/bc/warranty.c b/bc/warranty.c
new file mode 100644 (file)
index 0000000..47f00ed
--- /dev/null
@@ -0,0 +1,75 @@
+/* warranty.c: warranty routines for bc. */
+
+/*  This file is part of GNU bc.
+    Copyright (C) 1991-1994, 1997, 2000, 2003, 2004 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to
+      The Free Software Foundation, Inc.
+      51 Franklin Street, Fifth Floor
+      Boston, MA 02110-1301  USA
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+
+#include "bcdefs.h"
+#include "proto.h"
+
+
+/* Print the welcome banner. */
+
+void 
+welcome()
+{
+  printf ("This is free software with ABSOLUTELY NO WARRANTY.\n");
+  printf ("For details type `warranty'. \n");
+}
+
+/* Print out the version information. */
+void
+show_bc_version()
+{
+  printf("%s %s\n%s\n", PACKAGE, VERSION, BC_COPYRIGHT);
+}
+
+
+/* Print out the warranty information. */
+
+void 
+warranty(prefix)
+     const char *prefix;
+{
+  printf ("\n%s", prefix);
+  show_bc_version ();
+  printf ("\n"
+"    This program is free software; you can redistribute it and/or modify\n"
+"    it under the terms of the GNU General Public License as published by\n"
+"    the Free Software Foundation; either version 2 of the License , or\n"
+"    (at your option) any later version.\n\n"
+"    This program is distributed in the hope that it will be useful,\n"
+"    but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+"    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
+"    GNU General Public License for more details.\n\n"
+"    You should have received a copy of the GNU General Public License\n"
+"    along with this program. If not, write to\n\n"
+"       The Free Software Foundation, Inc.\n"
+"       51 Franklin Street, Fifth Floor\n"
+"       Boston, MA 02110-1301  USA\n\n");
+}
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..2e5ab06
--- /dev/null
@@ -0,0 +1,123 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define the bc copyright line. */
+#undef BC_COPYRIGHT
+
+/* Define the dc copyright line. */
+#undef DC_COPYRIGHT
+
+/* Define the dc version number. */
+#undef DC_VERSION
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the `fstat' function. */
+#undef HAVE_FSTAT
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `isgraph' function. */
+#undef HAVE_ISGRAPH
+
+/* Define to 1 if you have the <lib.h> header file. */
+#undef HAVE_LIB_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `setvbuf' function. */
+#undef HAVE_SETVBUF
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define if libedit is used */
+#undef LIBEDIT
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define if readline is used */
+#undef READLINE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+   `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `size_t' if <sys/types.h> does not define. */
+#undef ptrdiff_t
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..2f162f0
--- /dev/null
+++ b/configure
@@ -0,0 +1,6858 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for bc 1.06.95.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='bc'
+PACKAGE_TARNAME='bc'
+PACKAGE_VERSION='1.06.95'
+PACKAGE_STRING='bc 1.06.95'
+PACKAGE_BUGREPORT=''
+
+ac_unique_file="doc/bc.1"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP LEX LEXLIB LEX_OUTPUT_ROOT YACC RANLIB ac_ct_RANLIB READLINELIB BC_VERSION DC_VERSION LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r "./$ac_unique_file") 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures bc 1.06.95 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of bc 1.06.95:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pkg              use software installed in /usr/pkg tree
+  --with-libedit          support fancy BSD command input editing
+  --with-readline         support fancy command input editing
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+bc configure 1.06.95
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by bc $as_me 1.06.95, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+am__api_version="1.9"
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { { echo "$as_me:$LINENO: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $.  echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # We used to keeping the `.' as first argument, in order to
+  # allow $(mkdir_p) to be used without argument.  As in
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.  However this is wrong
+  # for two reasons:
+  #  1. if the package is installed by a user who cannot write `.'
+  #     make install will fail,
+  #  2. the above comment should most certainly read
+  #     $(mkdir_p) $(DESTDIR)$(somedir)
+  #     so it does not work when $(somedir) is undefined and
+  #     $(DESTDIR) is not.
+  #  To support the latter case, we have to write
+  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+  #  so the `.' trick is pointless.
+  mkdir_p='mkdir -p --'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='bc'
+ VERSION='1.06.95'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define DC_VERSION "1.3.95"
+_ACEOF
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define BC_COPYRIGHT "Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc."
+_ACEOF
+
+
+
+cat >>confdefs.h <<\_ACEOF
+#define DC_COPYRIGHT "Copyright 1994, 1997, 1998, 2000, 2001, 2004, 2005, 2006 Free Software Foundation, Inc."
+_ACEOF
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+       ;;
+    conftest.$ac_ext )
+       # This is the source file.
+       ;;
+    [ab].out )
+       # We found the default executable, but exeext='' is most
+       # certainly right.
+       break;;
+    *.* )
+       ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+       # FIXME: I believe we export ac_cv_exeext for Libtool,
+       # but it would be cool to find out if it's true.  Does anybody
+       # maintain Libtool? --akim.
+       export ac_cv_exeext
+       break;;
+    * )
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+         export ac_cv_exeext
+         break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+          ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+       @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+  enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CC"   am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking minix/config.h usability" >&5
+echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <minix/config.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking minix/config.h presence" >&5
+echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <minix/config.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: minix/config.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: minix/config.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ----------------------------- ##
+## Report this to the bc lists.  ##
+## ----------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for minix/config.h" >&5
+echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6
+if test "${ac_cv_header_minix_config_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_minix_config_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5
+echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6
+
+fi
+if test $ac_cv_header_minix_config_h = yes; then
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+if test "$MINIX" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_SOURCE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _POSIX_1_SOURCE 2
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _MINIX 1
+_ACEOF
+
+fi
+
+
+for ac_prog in flex lex
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_LEX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$LEX"; then
+  ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_LEX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+LEX=$ac_cv_prog_LEX
+if test -n "$LEX"; then
+  echo "$as_me:$LINENO: result: $LEX" >&5
+echo "${ECHO_T}$LEX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=":"
+
+if test -z "$LEXLIB"
+then
+  echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5
+echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6
+if test "${ac_cv_lib_fl_yywrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char yywrap ();
+int
+main ()
+{
+yywrap ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_fl_yywrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_fl_yywrap=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5
+echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6
+if test $ac_cv_lib_fl_yywrap = yes; then
+  LEXLIB="-lfl"
+else
+  echo "$as_me:$LINENO: checking for yywrap in -ll" >&5
+echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6
+if test "${ac_cv_lib_l_yywrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ll  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char yywrap ();
+int
+main ()
+{
+yywrap ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_l_yywrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_l_yywrap=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5
+echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6
+if test $ac_cv_lib_l_yywrap = yes; then
+  LEXLIB="-ll"
+fi
+
+fi
+
+fi
+
+if test "x$LEX" != "x:"; then
+  echo "$as_me:$LINENO: checking lex output file root" >&5
+echo $ECHO_N "checking lex output file root... $ECHO_C" >&6
+if test "${ac_cv_prog_lex_root+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # The minimal lex program is just a single line: %%.  But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+cat >conftest.l <<_ACEOF
+%%
+%%
+_ACEOF
+{ (eval echo "$as_me:$LINENO: \"$LEX conftest.l\"") >&5
+  (eval $LEX conftest.l) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+if test -f lex.yy.c; then
+  ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+  ac_cv_prog_lex_root=lexyy
+else
+  { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5
+echo "$as_me: error: cannot find output from $LEX; giving up" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5
+echo "${ECHO_T}$ac_cv_prog_lex_root" >&6
+rm -f conftest.l
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5
+echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6
+if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS=$LIBS
+LIBS="$LIBS $LEXLIB"
+cat >conftest.$ac_ext <<_ACEOF
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_lex_yytext_pointer=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_save_LIBS
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5
+echo "${ECHO_T}$ac_cv_prog_lex_yytext_pointer" >&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define YYTEXT_POINTER 1
+_ACEOF
+
+fi
+
+fi
+if test "$LEX" = :; then
+  LEX=${am_missing_run}flex
+fi
+for ac_prog in 'bison -y' byacc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_YACC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_YACC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  echo "$as_me:$LINENO: result: $YACC" >&5
+echo "${ECHO_T}$YACC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+
+
+
+
+
+
+
+
+for ac_header in stdarg.h stddef.h stdlib.h string.h errno.h limits.h unistd.h lib.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ----------------------------- ##
+## Report this to the bc lists.  ##
+## ----------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for size_t" >&5
+echo $ECHO_N "checking for size_t... $ECHO_C" >&6
+if test "${ac_cv_type_size_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+  return 0;
+if (sizeof (size_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_size_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_size_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for ptrdiff_t" >&5
+echo $ECHO_N "checking for ptrdiff_t... $ECHO_C" >&6
+if test "${ac_cv_type_ptrdiff_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((ptrdiff_t *) 0)
+  return 0;
+if (sizeof (ptrdiff_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_ptrdiff_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_ptrdiff_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_ptrdiff_t" >&5
+echo "${ECHO_T}$ac_cv_type_ptrdiff_t" >&6
+if test $ac_cv_type_ptrdiff_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define ptrdiff_t size_t
+_ACEOF
+
+fi
+
+
+
+for ac_func in vprintf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+echo "$as_me:$LINENO: checking for _doprnt" >&5
+echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
+if test "${ac_cv_func__doprnt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define _doprnt to an innocuous variant, in case <limits.h> declares _doprnt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define _doprnt innocuous__doprnt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef _doprnt
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char _doprnt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+char (*f) () = _doprnt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != _doprnt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func__doprnt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func__doprnt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
+echo "${ECHO_T}$ac_cv_func__doprnt" >&6
+if test $ac_cv_func__doprnt = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DOPRNT 1
+_ACEOF
+
+fi
+
+fi
+done
+
+
+
+
+
+
+for ac_func in isgraph setvbuf fstat strtol
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+# Check whether --with-pkg or --without-pkg was given.
+if test "${with_pkg+set}" = set; then
+  withval="$with_pkg"
+  case $withval in no) ;;
+      *) CPPFLAGS="$CPPFLAGS -I/usr/pkg/include"
+        LDFLAGS="$LDFLAGS -L/usr/pkg/lib"
+        echo Using /usr/pkg/include and /usr/pkg/lib ;;
+    esac
+fi;
+
+bcle=n
+
+# Check whether --with-libedit or --without-libedit was given.
+if test "${with_libedit+set}" = set; then
+  withval="$with_libedit"
+  case $withval in no) ;;
+      *) LDSAVE=$LDFLAGS
+        echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5
+echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6
+if test "${ac_cv_lib_termcap_tgetent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltermcap  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char tgetent ();
+int
+main ()
+{
+tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_termcap_tgetent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_termcap_tgetent=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_termcap_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6
+if test $ac_cv_lib_termcap_tgetent = yes; then
+  TERMLIB=-ltermcap
+fi
+
+        LDFLAGS="$LDFLAGS $TERMLIB"
+        echo "$as_me:$LINENO: checking for el_gets in -ledit" >&5
+echo $ECHO_N "checking for el_gets in -ledit... $ECHO_C" >&6
+if test "${ac_cv_lib_edit_el_gets+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ledit  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char el_gets ();
+int
+main ()
+{
+el_gets ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_edit_el_gets=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_edit_el_gets=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_edit_el_gets" >&5
+echo "${ECHO_T}$ac_cv_lib_edit_el_gets" >&6
+if test $ac_cv_lib_edit_el_gets = yes; then
+  if test "${ac_cv_header_histedit_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for histedit.h" >&5
+echo $ECHO_N "checking for histedit.h... $ECHO_C" >&6
+if test "${ac_cv_header_histedit_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_histedit_h" >&5
+echo "${ECHO_T}$ac_cv_header_histedit_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking histedit.h usability" >&5
+echo $ECHO_N "checking histedit.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <histedit.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking histedit.h presence" >&5
+echo $ECHO_N "checking histedit.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <histedit.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: histedit.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: histedit.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: histedit.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: histedit.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: histedit.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: histedit.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: histedit.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: histedit.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: histedit.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: histedit.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: histedit.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: histedit.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: histedit.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: histedit.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: histedit.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: histedit.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ----------------------------- ##
+## Report this to the bc lists.  ##
+## ----------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for histedit.h" >&5
+echo $ECHO_N "checking for histedit.h... $ECHO_C" >&6
+if test "${ac_cv_header_histedit_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_histedit_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_histedit_h" >&5
+echo "${ECHO_T}$ac_cv_header_histedit_h" >&6
+
+fi
+if test $ac_cv_header_histedit_h = yes; then
+  READLINELIB="-ledit $TERMLIB";bcle=y
+fi
+
+
+else
+  READLINELIB=""
+fi
+
+        case $bcle in
+          y)
+cat >>confdefs.h <<\_ACEOF
+#define LIBEDIT 1
+_ACEOF
+
+             echo Using the libedit library. ;;
+        esac
+        LDFLAGS=$LDSAVE
+        ;;
+    esac
+fi;
+
+bcrl=n
+
+# Check whether --with-readline or --without-readline was given.
+if test "${with_readline+set}" = set; then
+  withval="$with_readline"
+  case $withval in no) ;;
+      *) LDSAVE=$LDFLAGS
+        echo "$as_me:$LINENO: checking for tparm in -lncurses" >&5
+echo $ECHO_N "checking for tparm in -lncurses... $ECHO_C" >&6
+if test "${ac_cv_lib_ncurses_tparm+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char tparm ();
+int
+main ()
+{
+tparm ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ncurses_tparm=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ncurses_tparm=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_tparm" >&5
+echo "${ECHO_T}$ac_cv_lib_ncurses_tparm" >&6
+if test $ac_cv_lib_ncurses_tparm = yes; then
+  TERMLIB=-lncurses
+else
+  echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5
+echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6
+if test "${ac_cv_lib_termcap_tgetent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltermcap  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char tgetent ();
+int
+main ()
+{
+tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_termcap_tgetent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_termcap_tgetent=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_termcap_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6
+if test $ac_cv_lib_termcap_tgetent = yes; then
+  TERMLIB=-ltermcap
+fi
+
+fi
+
+        LDFLAGS="$LDFLAGS $TERMLIB"
+        echo "$as_me:$LINENO: checking for readline in -lreadline" >&5
+echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6
+if test "${ac_cv_lib_readline_readline+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char readline ();
+int
+main ()
+{
+readline ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_readline_readline=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_readline_readline=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5
+echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6
+if test $ac_cv_lib_readline_readline = yes; then
+  if test "${ac_cv_header_readline_readline_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for readline/readline.h" >&5
+echo $ECHO_N "checking for readline/readline.h... $ECHO_C" >&6
+if test "${ac_cv_header_readline_readline_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_readline_readline_h" >&5
+echo "${ECHO_T}$ac_cv_header_readline_readline_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking readline/readline.h usability" >&5
+echo $ECHO_N "checking readline/readline.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <readline/readline.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking readline/readline.h presence" >&5
+echo $ECHO_N "checking readline/readline.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <readline/readline.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: readline/readline.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: readline/readline.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline/readline.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: readline/readline.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: readline/readline.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: readline/readline.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline/readline.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: readline/readline.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline/readline.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: readline/readline.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline/readline.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: readline/readline.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline/readline.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: readline/readline.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: readline/readline.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: readline/readline.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ----------------------------- ##
+## Report this to the bc lists.  ##
+## ----------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for readline/readline.h" >&5
+echo $ECHO_N "checking for readline/readline.h... $ECHO_C" >&6
+if test "${ac_cv_header_readline_readline_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_readline_readline_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_readline_readline_h" >&5
+echo "${ECHO_T}$ac_cv_header_readline_readline_h" >&6
+
+fi
+if test $ac_cv_header_readline_readline_h = yes; then
+  READLINELIB="-lreadline $TERMLIB";bcrl=y
+fi
+
+
+else
+  READLINELIB=""
+fi
+
+        case $bcrl in
+          y)
+cat >>confdefs.h <<\_ACEOF
+#define READLINE 1
+_ACEOF
+
+             echo Using the readline library. ;;
+        esac
+        LDFLAGS=$LDSAVE
+        ;;
+    esac
+fi;
+
+case $bcle-$bcrl-$LEX in
+   y-y-*)
+       { { echo "$as_me:$LINENO: error: Can not use both readline and libedit.  Aborting." >&5
+echo "$as_me: error: Can not use both readline and libedit.  Aborting." >&2;}
+   { (exit 1); exit 1; }; } ;;
+   ?-?-flex)
+       LEX="flex -I -8"
+       case $bcrl in
+         n) { echo "$as_me:$LINENO: WARNING: readline works only with flex." >&5
+echo "$as_me: WARNING: readline works only with flex." >&2;} ;;
+       esac ;;
+esac
+
+case $LEX-`uname -s` in
+  lex-SunOS) LEXLIB=""; echo "SunOS using lex does not have a -ll." ;;
+esac
+
+case $GCC in
+  yes) CFLAGS="$CFLAGS -Wall -funsigned-char"
+       echo "Adding GCC specific compile flags." ;;
+esac
+
+
+BC_VERSION=1.06.95
+
+DC_VERSION=1.3.95
+
+                                                            ac_config_files="$ac_config_files Makefile bc/Makefile dc/Makefile doc/Makefile doc/texi-ver.incl lib/Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by bc $as_me 1.06.95, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+                  instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+bc config.status 1.06.95
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "bc/Makefile" ) CONFIG_FILES="$CONFIG_FILES bc/Makefile" ;;
+  "dc/Makefile" ) CONFIG_FILES="$CONFIG_FILES dc/Makefile" ;;
+  "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+  "doc/texi-ver.incl" ) CONFIG_FILES="$CONFIG_FILES doc/texi-ver.incl" ;;
+  "lib/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
+  "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@mkdir_p@,$mkdir_p,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@am__tar@,$am__tar,;t t
+s,@am__untar@,$am__untar,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@LEX@,$LEX,;t t
+s,@LEXLIB@,$LEXLIB,;t t
+s,@LEX_OUTPUT_ROOT@,$LEX_OUTPUT_ROOT,;t t
+s,@YACC@,$YACC,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@READLINELIB@,$READLINELIB,;t t
+s,@BC_VERSION@,$BC_VERSION,;t t
+s,@DC_VERSION@,$DC_VERSION,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([   ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[        ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([   ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        # Do quote $f, to prevent DOS paths from being IFS'd.
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[      ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[    ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[     ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[     ]*#[    ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[     ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $ac_file | $ac_file:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X$ac_file : 'X\(//\)[^/]' \| \
+        X$ac_file : 'X\(//\)$' \| \
+        X$ac_file : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+  ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+  ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+  ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_dest" : 'X\(//\)[^/]' \| \
+        X"$ac_dest" : 'X\(//\)$' \| \
+        X"$ac_dest" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+  case $ac_dest in
+    depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$mf" : 'X\(//\)[^/]' \| \
+        X"$mf" : 'X\(//\)$' \| \
+        X"$mf" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  else
+    continue
+  fi
+  # Extract the definition of DEPDIR, am__include, and am__quote
+  # from the Makefile without running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  am__include=`sed -n 's/^am__include = //p' < "$mf"`
+  test -z "am__include" && continue
+  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  # Find all dependency output files, they are included files with
+  # $(DEPDIR) in their names.  We invoke sed twice because it is the
+  # simplest approach to changing $(DEPDIR) to its actual value in the
+  # expansion.
+  for file in `sed -n "
+    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$file" : 'X\(//\)[^/]' \| \
+        X"$file" : 'X\(//\)$' \| \
+        X"$file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    { if $as_mkdir_p; then
+    mkdir -p $dirpart/$fdir
+  else
+    as_dir=$dirpart/$fdir
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+ ;;
+  esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..68d23ce
--- /dev/null
@@ -0,0 +1,127 @@
+dnl Process this file with autoconf to produce a configure script.
+
+dnl Copyright (C) 2006 Free Software Foundation, Inc.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2, or (at your option)
+dnl any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software Foundation,
+dnl Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+m4_define([bc_version], 1.06.95)
+m4_define([dc_version], 1.3.95)
+
+AC_INIT(bc, bc_version)
+AC_CONFIG_SRCDIR(doc/bc.1)
+AM_INIT_AUTOMAKE([dist-bzip2])
+AM_CONFIG_HEADER(config.h)
+
+AC_DEFINE([DC_VERSION], "dc_version",
+         [Define the dc version number.])
+
+AC_DEFINE([BC_COPYRIGHT],
+         ["Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc."],
+         [Define the bc copyright line.])
+
+AC_DEFINE([DC_COPYRIGHT], 
+          ["Copyright 1994, 1997, 1998, 2000, 2001, 2004, 2005, 2006 Free Software Foundation, Inc."],
+         [Define the dc copyright line.])
+
+AC_PROG_CC
+AC_MINIX
+
+AM_PROG_LEX
+AC_PROG_YACC
+AC_PROG_INSTALL
+AC_PROG_RANLIB
+AC_PROG_MAKE_SET
+
+AC_CHECK_HEADERS(stdarg.h stddef.h stdlib.h string.h errno.h limits.h unistd.h lib.h)
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_CHECK_TYPE(ptrdiff_t, size_t)
+
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(isgraph setvbuf fstat strtol)
+
+AC_ARG_WITH(pkg,
+   AC_HELP_STRING([--with-pkg],
+      [use software installed in /usr/pkg tree]),
+   [case $withval in no) ;;
+      *) CPPFLAGS="$CPPFLAGS -I/usr/pkg/include"
+        LDFLAGS="$LDFLAGS -L/usr/pkg/lib"
+        echo Using /usr/pkg/include and /usr/pkg/lib ;;
+    esac])
+
+bcle=n
+AC_ARG_WITH(libedit,
+   AC_HELP_STRING([--with-libedit],
+      [support fancy BSD command input editing]),
+   [case $withval in no) ;;
+      *) LDSAVE=$LDFLAGS
+        AC_CHECK_LIB(termcap,tgetent,TERMLIB=-ltermcap)
+        LDFLAGS="$LDFLAGS $TERMLIB"
+        AC_CHECK_LIB(edit,el_gets,
+           [AC_CHECK_HEADER(histedit.h,
+            READLINELIB="-ledit $TERMLIB";bcle=y)],
+           READLINELIB="")
+        case $bcle in
+          y) AC_DEFINE(LIBEDIT,1, [Define if libedit is used])
+             echo Using the libedit library. ;;
+        esac
+        LDFLAGS=$LDSAVE
+        ;;
+    esac])
+bcrl=n
+AC_ARG_WITH(readline,
+   AC_HELP_STRING([--with-readline],
+      [support fancy command input editing]),
+   [case $withval in no) ;;
+      *) LDSAVE=$LDFLAGS
+        AC_CHECK_LIB(ncurses,tparm,TERMLIB=-lncurses,
+           AC_CHECK_LIB(termcap,tgetent,TERMLIB=-ltermcap))
+        LDFLAGS="$LDFLAGS $TERMLIB"
+        AC_CHECK_LIB(readline,readline,
+           [AC_CHECK_HEADER(readline/readline.h,
+            READLINELIB="-lreadline $TERMLIB";bcrl=y)],
+           READLINELIB="")
+        case $bcrl in
+          y) AC_DEFINE(READLINE,1, [Define if readline is used])
+             echo Using the readline library. ;;
+        esac
+        LDFLAGS=$LDSAVE
+        ;;
+    esac])
+
+case $bcle-$bcrl-$LEX in
+   y-y-*)
+       AC_MSG_ERROR(Can not use both readline and libedit.  Aborting.) ;;
+   ?-?-flex)
+       LEX="flex -I -8"
+       case $bcrl in
+         n) AC_MSG_WARN(readline works only with flex.) ;;
+       esac ;;
+esac
+
+case $LEX-`uname -s` in
+  lex-SunOS) LEXLIB=""; echo "SunOS using lex does not have a -ll." ;;
+esac
+
+case $GCC in
+  yes) CFLAGS="$CFLAGS -Wall -funsigned-char"
+       echo "Adding GCC specific compile flags." ;;
+esac
+
+AC_SUBST(READLINELIB)
+AC_SUBST(BC_VERSION, bc_version)
+AC_SUBST(DC_VERSION, dc_version)
+AC_OUTPUT(Makefile bc/Makefile dc/Makefile doc/Makefile doc/texi-ver.incl lib/Makefile)
diff --git a/dc/Makefile.am b/dc/Makefile.am
new file mode 100644 (file)
index 0000000..6e3d1f9
--- /dev/null
@@ -0,0 +1,14 @@
+## Process this file with automake to produce Makefile.in
+bin_PROGRAMS = dc
+
+dc_SOURCES = dc.c misc.c eval.c stack.c array.c numeric.c string.c
+noinst_HEADERS = dc.h dc-proto.h dc-regdef.h
+
+INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../h
+LDADD = ../lib/libbc.a
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CFLAGS = @CFLAGS@
+
+$(PROGRAMS): $(LDADD)
diff --git a/dc/Makefile.in b/dc/Makefile.in
new file mode 100644 (file)
index 0000000..05139e3
--- /dev/null
@@ -0,0 +1,417 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+bin_PROGRAMS = dc$(EXEEXT)
+subdir = dc
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in TODO
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_dc_OBJECTS = dc.$(OBJEXT) misc.$(OBJEXT) eval.$(OBJEXT) \
+       stack.$(OBJEXT) array.$(OBJEXT) numeric.$(OBJEXT) \
+       string.$(OBJEXT)
+dc_OBJECTS = $(am_dc_OBJECTS)
+dc_LDADD = $(LDADD)
+dc_DEPENDENCIES = ../lib/libbc.a
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(dc_SOURCES)
+DIST_SOURCES = $(dc_SOURCES)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BC_VERSION = @BC_VERSION@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DC_VERSION = @DC_VERSION@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+READLINELIB = @READLINELIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+dc_SOURCES = dc.c misc.c eval.c stack.c array.c numeric.c string.c
+noinst_HEADERS = dc.h dc-proto.h dc-regdef.h
+INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../h
+LDADD = ../lib/libbc.a
+MAINTAINERCLEANFILES = Makefile.in
+AM_CFLAGS = @CFLAGS@
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  dc/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  dc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         if test -f $$p \
+         ; then \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+          echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+         else :; fi; \
+       done
+
+uninstall-binPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(bin_PROGRAMS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+         echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+         rm -f "$(DESTDIR)$(bindir)/$$f"; \
+       done
+
+clean-binPROGRAMS:
+       -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+dc$(EXEEXT): $(dc_OBJECTS) $(dc_DEPENDENCIES) 
+       @rm -f dc$(EXEEXT)
+       $(LINK) $(dc_LDFLAGS) $(dc_OBJECTS) $(dc_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/numeric.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+         test -n "$$unique" || unique=$$empty_fix; \
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+           $$tags $$unique; \
+       fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+       for dir in "$(DESTDIR)$(bindir)"; do \
+         test -z "$$dir" || $(mkdir_p) "$$dir"; \
+       done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+       clean-generic ctags distclean distclean-compile \
+       distclean-generic distclean-tags distdir dvi dvi-am html \
+       html-am info info-am install install-am install-binPROGRAMS \
+       install-data install-data-am install-exec install-exec-am \
+       install-info install-info-am install-man install-strip \
+       installcheck installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+       uninstall-am uninstall-binPROGRAMS uninstall-info-am
+
+
+$(PROGRAMS): $(LDADD)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/dc/TODO b/dc/TODO
new file mode 100644 (file)
index 0000000..555f30a
--- /dev/null
+++ b/dc/TODO
@@ -0,0 +1 @@
+Add gettext support
diff --git a/dc/array.c b/dc/array.c
new file mode 100644 (file)
index 0000000..afcdb14
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * implement arrays for dc
+ *
+ * Copyright (C) 1994, 1997, 1998, 2000, 2006 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, you can either send email to this
+ * program's author (see below) or write to:
+ *
+ *    The Free Software Foundation, Inc.
+ *    51 Franklin Street, Fifth Floor
+ *    Boston, MA 02110-1301  USA
+ */
+
+/* This module is the only one that knows what arrays look like. */
+
+#include "config.h"
+
+#include <stdio.h>     /* "dc-proto.h" wants this */
+#ifdef HAVE_STDLIB_H
+/* get size_t definition from "almost ANSI" compiling environments. */
+#include <stdlib.h>
+#endif
+#include "dc.h"
+#include "dc-proto.h"
+#include "dc-regdef.h"
+
+/* what's most useful: quick access or sparse arrays? */
+/* I'll go with sparse arrays for now */
+struct dc_array {
+       int Index;
+       dc_data value;
+       struct dc_array *next;
+};
+
+
+/* initialize the arrays */
+void
+dc_array_init DC_DECLVOID()
+{
+}
+
+/* store value into array_id[Index] */
+void
+dc_array_set DC_DECLARG((array_id, Index, value))
+       int array_id DC_DECLSEP
+       int Index DC_DECLSEP
+       dc_data value DC_DECLEND
+{
+       struct dc_array *cur;
+       struct dc_array *prev = NULL;
+
+       cur = dc_get_stacked_array(array_id);
+       while (cur != NULL  &&  cur->Index < Index){
+               prev = cur;
+               cur = cur->next;
+       }
+       if (cur != NULL  &&  cur->Index == Index){
+               if (cur->value.dc_type == DC_NUMBER)
+                       dc_free_num(&cur->value.v.number);
+               else if (cur->value.dc_type == DC_STRING)
+                       dc_free_str(&cur->value.v.string);
+               else
+                       dc_garbage(" in array", array_id);
+               cur->value = value;
+       }else{
+               struct dc_array *newentry = dc_malloc(sizeof *newentry);
+               newentry->Index = Index;
+               newentry->value = value;
+               newentry->next = cur;
+               if (prev != NULL)
+                       prev->next = newentry;
+               else
+                       dc_set_stacked_array(array_id, newentry);
+       }
+}
+
+/* retrieve a dup of a value from array_id[Index] */
+/* A zero value is returned if the specified value is unintialized. */
+dc_data
+dc_array_get DC_DECLARG((array_id, Index))
+       int array_id DC_DECLSEP
+       int Index DC_DECLEND
+{
+       struct dc_array *cur = dc_get_stacked_array(array_id);
+
+       while (cur != NULL  &&  cur->Index < Index)
+               cur = cur->next;
+       if (cur !=NULL  &&  cur->Index == Index)
+               return dc_dup(cur->value);
+       return dc_int2data(0);
+}
+
+/* free an array chain */
+void
+dc_array_free DC_DECLARG((a_head))
+       struct dc_array *a_head DC_DECLEND
+{
+       struct dc_array *cur;
+       struct dc_array *next;
+
+       for (cur=a_head; cur!=NULL; cur=next) {
+               next = cur->next;
+               if (cur->value.dc_type == DC_NUMBER)
+                       dc_free_num(&cur->value.v.number);
+               else if (cur->value.dc_type == DC_STRING)
+                       dc_free_str(&cur->value.v.string);
+               else
+                       dc_garbage("in stack", -1);
+               free(cur);
+       }
+}
+
+\f
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 4
+ * End:
+ * vi: set ts=4 :
+ */
diff --git a/dc/dc-proto.h b/dc/dc-proto.h
new file mode 100644 (file)
index 0000000..c1ee5eb
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * prototypes of all externally visible dc functions
+ *
+ * Copyright (C) 1994, 1997, 1998, 2003 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, you can either send email to this
+ * program's author (see below) or write to:
+ *
+ *    The Free Software Foundation, Inc.
+ *    51 Franklin Street, Fifth Floor
+ *    Boston, MA 02110-1301  USA
+ */
+
+extern const char *dc_str2charp DC_PROTO((dc_str));
+extern const char *dc_system DC_PROTO((const char *));
+extern void *dc_malloc DC_PROTO((size_t));
+extern struct dc_array *dc_get_stacked_array DC_PROTO((int));
+
+extern void dc_array_set DC_PROTO((int, int, dc_data));
+extern void dc_array_free DC_PROTO((struct dc_array *));
+extern void dc_array_init DC_PROTO((void));
+extern void dc_binop DC_PROTO((int (*)(dc_num, dc_num, int, dc_num *), int));
+extern void dc_binop2 DC_PROTO((int (*)(dc_num, dc_num, int,
+                                                               dc_num *, dc_num *), int));
+extern void dc_triop DC_PROTO((int (*)(dc_num, dc_num, dc_num, int,
+                                                               dc_num *), int));
+extern void dc_clear_stack DC_PROTO((void));
+extern void dc_dump_num(dc_num, dc_discard);
+extern void dc_free_num DC_PROTO((dc_num *));
+extern void dc_free_str DC_PROTO((dc_str *));
+extern void dc_garbage DC_PROTO((const char *, int));
+extern void dc_math_init DC_PROTO((void));
+extern void dc_memfail DC_PROTO((void));
+extern void dc_out_num DC_PROTO((dc_num, int, dc_newline, dc_discard));
+extern void dc_out_str DC_PROTO((dc_str, dc_newline, dc_discard));
+extern void dc_print DC_PROTO((dc_data, int, dc_newline, dc_discard));
+extern void dc_printall DC_PROTO((int));
+extern void dc_push DC_PROTO((dc_data));
+extern void dc_register_init DC_PROTO((void));
+extern void dc_register_push DC_PROTO((int, dc_data));
+extern void dc_register_set DC_PROTO((int, dc_data));
+extern void dc_set_stacked_array DC_PROTO((int, struct dc_array *));
+extern void dc_show_id DC_PROTO((FILE *, int, const char *));
+extern void dc_string_init DC_PROTO((void));
+
+extern int  dc_cmpop DC_PROTO((void));
+extern int  dc_compare DC_PROTO((dc_num, dc_num));
+extern int  dc_evalfile DC_PROTO((FILE *));
+extern int  dc_evalstr DC_PROTO((dc_data *));
+extern int  dc_num2int DC_PROTO((dc_num, dc_discard));
+extern int  dc_numlen DC_PROTO((dc_num));
+extern int  dc_pop DC_PROTO((dc_data *));
+extern int  dc_register_get DC_PROTO((int, dc_data *));
+extern int  dc_register_pop DC_PROTO((int, dc_data *));
+extern int  dc_tell_length DC_PROTO((dc_data, dc_discard));
+extern int  dc_tell_scale DC_PROTO((dc_num, dc_discard));
+extern int  dc_tell_stackdepth DC_PROTO((void));
+extern int  dc_top_of_stack DC_PROTO((dc_data *));
+
+extern size_t dc_strlen DC_PROTO((dc_str));
+
+extern dc_data dc_array_get DC_PROTO((int, int));
+extern dc_data dc_dup DC_PROTO((dc_data));
+extern dc_data dc_dup_num DC_PROTO((dc_num));
+extern dc_data dc_dup_str DC_PROTO((dc_str));
+extern dc_data dc_getnum DC_PROTO((int (*)(void), int, int *));
+extern dc_data dc_int2data DC_PROTO((int));
+extern dc_data dc_makestring DC_PROTO((const char *, size_t));
+extern dc_data dc_readstring DC_PROTO((FILE *, int , int));
+
+extern int dc_add DC_PROTO((dc_num, dc_num, int, dc_num *));
+extern int dc_div DC_PROTO((dc_num, dc_num, int, dc_num *));
+extern int dc_divrem DC_PROTO((dc_num, dc_num, int, dc_num *, dc_num *));
+extern int dc_exp DC_PROTO((dc_num, dc_num, int, dc_num *));
+extern int dc_modexp DC_PROTO((dc_num, dc_num, dc_num, int, dc_num *));
+extern int dc_mul DC_PROTO((dc_num, dc_num, int, dc_num *));
+extern int dc_rem DC_PROTO((dc_num, dc_num, int, dc_num *));
+extern int dc_sub DC_PROTO((dc_num, dc_num, int, dc_num *));
+extern int dc_sqrt DC_PROTO((dc_num, int, dc_num *));
diff --git a/dc/dc-regdef.h b/dc/dc-regdef.h
new file mode 100644 (file)
index 0000000..af64082
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * definitions for dc's "register" declarations
+ *
+ * Copyright (C) 1994, 2000 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, you can either send email to this
+ * program's author (see below) or write to:
+ *
+ *    The Free Software Foundation, Inc.
+ *    51 Franklin Street, Fifth Floor
+ *    Boston, MA 02110-1301  USA
+ */
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h>   /* UCHAR_MAX */
+#endif
+#ifndef UCHAR_MAX
+# define UCHAR_MAX ((unsigned char)~0)
+#endif
+
+/* determine how many register stacks there are */
+#ifndef DC_REGCOUNT
+# define DC_REGCOUNT (UCHAR_MAX+1)
+#endif
+
+/* efficiency hack for masking arbritrary integers to 0..(DC_REGCOUNT-1) */
+#if (DC_REGCOUNT & (DC_REGCOUNT-1)) == 0       /* DC_REGCOUNT is power of 2 */
+# define regmap(r)     ((r) & (DC_REGCOUNT-1))
+#else
+# define regmap(r)     ((r) % DC_REGCOUNT)
+#endif
diff --git a/dc/dc.c b/dc/dc.c
new file mode 100644 (file)
index 0000000..e03f094
--- /dev/null
+++ b/dc/dc.c
@@ -0,0 +1,319 @@
+/*
+ * implement the "dc" Desk Calculator language.
+ *
+ * Copyright (C) 1994, 1997, 1998, 2000, 2003, 2006 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, you can either send email to this
+ * program's author (see below) or write to:
+ *   The Free Software Foundation, Inc.
+ *   51 Franklin Street, Fifth Floor
+ *   Boston, MA 02110-1301  USA
+ */
+
+/* Written with strong hiding of implementation details
+ * in their own specialized modules.
+ */
+/* This module contains the argument processing/main functions.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif
+#ifdef HAVE_FSTAT
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+#include <getopt.h>
+#include "dc.h"
+#include "dc-proto.h"
+
+#ifndef EXIT_SUCCESS   /* C89 <stdlib.h> */
+# define EXIT_SUCCESS  0
+#endif
+#ifndef EXIT_FAILURE   /* C89 <stdlib.h> */
+# define EXIT_FAILURE  1
+#endif
+
+const char *progname;  /* basename of program invocation */
+
+static void
+bug_report_info DC_DECLVOID()
+{
+       printf("Email bug reports to:  bug-dc@gnu.org .\n");
+}
+
+static void
+show_version DC_DECLVOID()
+{
+       printf("dc (GNU %s %s) %s\n", PACKAGE, VERSION, DC_VERSION);
+       printf("\n%s\n\
+This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n\
+to the extent permitted by law.\n", DC_COPYRIGHT);
+}
+
+/* your generic usage function */
+static void
+usage DC_DECLARG((f))
+       FILE *f DC_DECLEND
+{
+       fprintf(f, "\
+Usage: %s [OPTION] [file ...]\n\
+  -e, --expression=EXPR    evaluate expression\n\
+  -f, --file=FILE          evaluate contents of file\n\
+  -h, --help               display this help and exit\n\
+  -V, --version            output version information and exit\n\
+\n\
+", progname);
+       bug_report_info();
+}
+
+/* returns a pointer to one past the last occurance of c in s,
+ * or s if c does not occur in s.
+ */
+static char *
+r1bindex DC_DECLARG((s, c))
+       char *s DC_DECLSEP
+       int  c DC_DECLEND
+{
+       char *p = strrchr(s, c);
+
+       if (p == NULL)
+               return s;
+       return p + 1;
+}
+
+static void
+try_file(const char *filename)
+{
+       FILE *input;
+
+       if (strcmp(filename, "-") == 0) {
+               input = stdin;
+       } else if ( (input=fopen(filename, "r")) == NULL ) {
+               fprintf(stderr, "%s: Could not open file %s\n", progname, filename);
+               return;
+       }
+       {
+           /* Several complaints have been filed about dc's silence
+            * when a "cd" typo is made.  I really wanted to avoid
+            * this mess, but I guess it really should be added...
+            */
+#ifndef HAVE_FSTAT
+           /* non-POSIXish system; this code _might_ notice a directory */
+           int c = getc(input);
+           if (c == EOF && ferror(input)) {
+                       perror(filename);
+                       goto close;
+           }
+           ungetc(c, input);
+
+#else /* HAVE_FSTAT */
+  /* If HAVE_FSTAT and no S_IS*() macros, it must be a pre-POSIX
+   * Unix-ish system?
+   */
+# ifndef S_ISREG
+#  ifdef S_IFREG
+#    define S_ISREG(m) (((m)&S_IFMT)==S_IFREG)
+#   else
+#    define S_ISREG(m) 0
+#  endif
+# endif
+# ifndef S_ISCHR
+#  ifdef S_IFCHR
+#   define S_ISCHR(m)  (((m)&S_IFMT)==S_IFCHR)
+#  endif
+# endif
+# ifndef S_ISFIFO
+#  ifdef S_IFIFO
+#   define S_ISFIFO(m) (((m)&S_IFMT)==S_IFIFO)
+#  endif
+# endif
+# ifndef S_ISSOCK
+#  ifdef S_IFSOCK
+#   define S_ISSOCK(m) (((m)&S_IFMT)==S_IFSOCK)
+#  endif
+# endif
+# ifndef S_ISDIR
+#  ifdef S_IFDIR
+#   define S_ISDIR(m)  (((m)&S_IFMT)==S_IFDIR)
+#  endif
+# endif
+# ifndef S_ISBLK
+#  ifdef S_IFBLK
+#   define S_ISBLK(m)  (((m)&S_IFMT)==S_IFBLK)
+#  endif
+# endif
+           struct stat s;
+           if (fstat(fileno(input), &s) == -1) {
+                       /* "can't happen" */
+                       fprintf(stderr, "%s: Could not fstat file ", progname);
+                       perror(filename);
+                       goto close;
+           }
+
+#ifdef S_ISDIR
+               if (S_ISDIR(s.st_mode)) {
+                       fprintf(stderr,
+                               "%s: Will not attempt to process directory %s\n",
+                               progname, filename);
+                       goto close;
+               } else
+#endif
+#ifdef S_ISBLK
+               if (S_ISBLK(s.st_mode)) {
+                       fprintf(stderr,
+                               "%s: Will not attempt to process block-special file %s\n",
+                               progname, filename);
+                       goto close;
+               } else
+#endif
+           if (!S_ISREG(s.st_mode)
+# ifdef S_ISCHR
+                       /* typically will be /dev/null or some sort of tty */
+                       && !S_ISCHR(s.st_mode)
+# endif
+# ifdef S_ISFIFO
+                       && !S_ISFIFO(s.st_mode)
+# endif
+# ifdef S_ISSOCK
+                       && !S_ISSOCK(s.st_mode)
+# endif
+                               ) {
+                       fprintf(stderr,
+                               "%s: Will not attempt to process file of unusual type: %s\n",
+                               progname, filename);
+                       goto close;
+           }
+#endif /* HAVE_FSTAT */
+       }
+       if (dc_evalfile(input) != DC_SUCCESS)
+               exit(EXIT_FAILURE);
+close:
+       if (input != stdin)
+               fclose(input);
+}
+
+\f
+
+/* Check to see if there were any output errors; if so, then give
+ * an error message (if stderr is not known to be unhappy), and
+ * ensure that the program exits with an error indication.
+ */
+static int
+flush_okay DC_DECLVOID()
+{
+       const char *errmsg = NULL;
+       int r = EXIT_SUCCESS;
+
+       if (ferror(stdout))
+               errmsg = "error writing to stdout";
+       else if (fflush(stdout))
+               errmsg = "error flushing stdout";
+       else if (fclose(stdout))
+               errmsg = "error closing stdout";
+
+       if (errmsg) {
+               fprintf(stderr, "%s: ", progname);
+               perror(errmsg);
+               r = EXIT_FAILURE;
+       }
+
+       if (ferror(stderr) || fclose(stderr))
+               r = EXIT_FAILURE;
+       return r;
+}
+
+\f
+int
+main DC_DECLARG((argc, argv))
+       int  argc DC_DECLSEP
+       char **argv DC_DECLEND
+{
+       static struct option const long_opts[] = {
+               {"expression", required_argument, NULL, 'e'},
+               {"file", required_argument, NULL, 'f'},
+               {"help", no_argument, NULL, 'h'},
+               {"version", no_argument, NULL, 'V'},
+               {NULL, 0, NULL, 0}
+       };
+       int did_eval = 0;
+       int c;
+
+       progname = r1bindex(*argv, '/');
+#ifdef HAVE_SETVBUF
+       /* attempt to simplify interaction with applications such as emacs */
+       (void) setvbuf(stdout, NULL, _IOLBF, 0);
+#endif
+       dc_math_init();
+       dc_string_init();
+       dc_register_init();
+       dc_array_init();
+
+       while ((c = getopt_long(argc, argv, "hVe:f:", long_opts, (int *)0)) != EOF) {
+               switch (c) {
+               case 'e':
+                       {       dc_data string = dc_makestring(optarg, strlen(optarg));
+                               if (dc_evalstr(&string) != DC_SUCCESS)
+                                       return flush_okay();
+                               dc_free_str(&string.v.string);
+                               did_eval = 1;
+                       }
+                       break;
+               case 'f':
+                       try_file(optarg);
+                       did_eval = 1;
+                       break;
+               case 'h':
+                       usage(stdout);
+                       return flush_okay();
+               case 'V':
+                       show_version();
+                       return flush_okay();
+               default:
+                       usage(stderr);
+                       return EXIT_FAILURE;
+               }
+       }
+
+       for (; optind < argc; ++optind) {
+               try_file(argv[optind]);
+               did_eval = 1;
+       }
+       if (did_eval == 0) {
+               /* if no -e commands and no command files, then eval stdin */
+               if (dc_evalfile(stdin) != DC_SUCCESS)
+                       return EXIT_FAILURE;
+       }
+       return flush_okay();
+}
+
+\f
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 4
+ * End:
+ * vi: set ts=4 :
+ */
diff --git a/dc/dc.h b/dc/dc.h
new file mode 100644 (file)
index 0000000..5dcf2f1
--- /dev/null
+++ b/dc/dc.h
@@ -0,0 +1,82 @@
+/*
+ * Header file for dc routines
+ *
+ * Copyright (C) 1994, 1997, 1998 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, you can either send email to this
+ * program's author (see below) or write to:
+ *
+ *    The Free Software Foundation, Inc.
+ *    51 Franklin Street, Fifth Floor
+ *    Boston, MA 02110-1301  USA
+ */
+
+#ifndef DC_DEFS_H
+#define DC_DEFS_H
+
+/* 'I' is a command, and bases 17 and 18 are quite
+ * unusual, so we limit ourselves to bases 2 to 16
+ */
+#define DC_IBASE_MAX   16
+
+#define DC_SUCCESS             0
+#define DC_DOMAIN_ERROR        1
+#define DC_FAIL                        2       /* generic failure */
+
+
+#ifndef __STDC__
+# define DC_PROTO(x)                   ()
+# define DC_DECLVOID()                 ()
+# define DC_DECLARG(arglist)   arglist
+# define DC_DECLSEP                            ;
+# define DC_DECLEND                            ;
+#else /* __STDC__ */
+# define DC_PROTO(x)                   x
+# define DC_DECLVOID()                 (void)
+# define DC_DECLARG(arglist)   (
+# define DC_DECLSEP                            ,
+# define DC_DECLEND                            )
+#endif /* __STDC__ */
+
+
+typedef enum {DC_TOSS, DC_KEEP}   dc_discard;
+typedef enum {DC_NONL, DC_WITHNL} dc_newline;
+
+
+/* type discriminant for dc_data */
+typedef enum {DC_UNINITIALIZED, DC_NUMBER, DC_STRING} dc_value_type;
+
+/* only numeric.c knows what dc_num's *really* look like */
+typedef struct dc_number *dc_num;
+
+/* only string.c knows what dc_str's *really* look like */
+typedef struct dc_string *dc_str;
+
+
+/* except for the two implementation-specific modules, all
+ * dc functions only know of this one generic type of object
+ */
+typedef struct {
+       dc_value_type dc_type;  /* discriminant for union */
+       union {
+               dc_num number;
+               dc_str string;
+       } v;
+} dc_data;
+
+
+/* This is dc's only global variable: */
+extern const char *progname;   /* basename of program invocation */
+
+#endif /* not DC_DEFS_H */
diff --git a/dc/eval.c b/dc/eval.c
new file mode 100644 (file)
index 0000000..4af7200
--- /dev/null
+++ b/dc/eval.c
@@ -0,0 +1,793 @@
+/*
+ * evaluate the dc language, from a FILE* or a string
+ *
+ * Copyright (C) 1994, 1997, 1998, 2000, 2003, 2005, 2006 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, you can either send email to this
+ * program's author (see below) or write to:
+ *   The Free Software Foundation, Inc.
+ *   51 Franklin Street, Fifth Floor
+ *   Boston, MA 02110-1301  USA
+ */
+
+/* This is the only module which knows about the dc input language */
+
+#include "config.h"
+
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+# include <string.h>   /* memchr */
+#else
+# ifdef HAVE_MEMORY_H
+#  include <memory.h>  /* memchr, maybe */
+# else
+#  ifdef HAVE_STRINGS_H
+#   include <strings.h>        /* memchr, maybe */
+#  endif
+#endif
+#endif
+#include <signal.h>
+#include "dc.h"
+#include "dc-proto.h"
+
+typedef enum {DC_FALSE, DC_TRUE} dc_boolean;
+
+typedef enum {
+       DC_OKAY = DC_SUCCESS, /* no further intervention needed for this command */
+       DC_EATONE,              /* caller needs to eat the lookahead char */
+       DC_EVALREG,             /* caller needs to eval the string named by `peekc' */
+       DC_EVALTOS,             /* caller needs to eval the string on top of the stack */
+       DC_QUIT,                /* quit out of unwind_depth levels of evaluation */
+       DC_INT,                 /* caller needs to parse a dc_num from input stream */
+       DC_STR,                 /* caller needs to parse a dc_str from input stream */
+       DC_SYSTEM,              /* caller needs to run a system() on next input line */
+       DC_COMMENT,             /* caller needs to skip to the next input line */
+       DC_NEGCMP,              /* caller needs to re-call dc_func() with `negcmp' set */
+
+       DC_EOF_ERROR    /* unexpected end of input; abort current eval */
+} dc_status;
+
+static int dc_ibase=10;                /* input base, 2 <= dc_ibase <= DC_IBASE_MAX */
+static int dc_obase=10;                /* output base, 2 <= dc_obase */
+static int dc_scale=0;         /* scale (see user documentaton) */
+
+/* for Quitting evaluations */
+static int unwind_depth=0;
+
+/* for handling SIGINT properly */
+static volatile sig_atomic_t interrupt_seen=0;
+
+/* if true, active Quit will not exit program */
+static dc_boolean unwind_noexit=DC_FALSE;
+
+/*
+ * Used to synchronize lookahead on stdin for '?' command.
+ * If set to EOF then lookahead is used up.
+ */
+static int stdin_lookahead=EOF;
+
+\f
+/* input_fil and input_str are passed as arguments to dc_getnum */
+
+/* used by the input_* functions: */
+static FILE *input_fil_fp;
+static const char *input_str_string;
+
+/* Since we have a need for two characters of pushback, and
+ * ungetc() only guarantees one, we place the second pushback here
+ */
+static int input_pushback;
+
+/* passed as an argument to dc_getnum */
+static int
+input_fil DC_DECLVOID()
+{
+       if (input_pushback != EOF){
+               int c = input_pushback;
+               input_pushback = EOF;
+               return c;
+       }
+       return getc(input_fil_fp);
+}
+
+/* passed as an argument to dc_getnum */
+static int
+input_str DC_DECLVOID()
+{
+       if (*input_str_string == '\0')
+               return EOF;
+       return *input_str_string++;
+}
+
+\f
+
+/* takes a string and evals it; frees the string when done */
+/* Wrapper around dc_evalstr to avoid duplicating the free call
+ * at all possible return points.
+ */
+static int
+dc_eval_and_free_str DC_DECLARG((string))
+       dc_data *string DC_DECLEND
+{
+       dc_status status;
+
+       status = dc_evalstr(string);
+       if (string->dc_type == DC_STRING)
+               dc_free_str(&string->v.string);
+       return status;
+}
+
+\f
+/* notice when an interrupt event happens */
+static void
+dc_trap_interrupt DC_DECLARG((signo))
+       int signo DC_DECLEND
+{
+       signal(signo, dc_trap_interrupt);
+       interrupt_seen = 1;
+}
+
+\f
+/* step pointer past next end-of-line (or to end-of-string) */
+static const char *
+skip_past_eol DC_DECLARG((strptr, strend))
+       const char *strptr DC_DECLSEP
+       const char *strend DC_DECLEND
+{
+       const char *p = memchr(strptr, '\n', (size_t)(strend-strptr));
+       if (p != NULL)
+               return p+1;
+       return strend;
+}
+
+\f
+/* dc_func does the grunt work of figuring out what each input
+ * character means; used by both dc_evalstr and dc_evalfile
+ *
+ * c -> the "current" input character under consideration
+ * peekc -> the lookahead input character
+ * negcmp -> negate comparison test (for <,=,> commands)
+ */
+static dc_status
+dc_func DC_DECLARG((c, peekc, negcmp))
+       int c DC_DECLSEP
+       int peekc DC_DECLSEP
+       int negcmp DC_DECLEND
+{
+       dc_data datum;
+       int tmpint;
+
+       switch (c){
+       case '_': case '.':
+       case '0': case '1': case '2': case '3':
+       case '4': case '5': case '6': case '7':
+       case '8': case '9': case 'A': case 'B':
+       case 'C': case 'D': case 'E': case 'F':
+               return DC_INT;
+       case ' ':
+       case '\t':
+       case '\n':
+               /* standard command separators */
+               break;
+
+       case '+':       /* add top two stack elements */
+               dc_binop(dc_add, dc_scale);
+               break;
+       case '-':       /* subtract top two stack elements */
+               dc_binop(dc_sub, dc_scale);
+               break;
+       case '*':       /* multiply top two stack elements */
+               dc_binop(dc_mul, dc_scale);
+               break;
+       case '/':       /* divide top two stack elements */
+               dc_binop(dc_div, dc_scale);
+               break;
+       case '%':
+               /* take the remainder from division of the top two stack elements */
+               dc_binop(dc_rem, dc_scale);
+               break;
+       case '~':
+               /* Do division on the top two stack elements.  Return the
+                * quotient as next-to-top of stack and the remainder as
+                * top-of-stack.
+                */
+               dc_binop2(dc_divrem, dc_scale);
+               break;
+       case '|':
+               /* Consider the top three elements of the stack as (base, exp, mod),
+                * where mod is top-of-stack, exp is next-to-top, and base is
+                * second-from-top. Mod must be non-zero, exp must be non-negative,
+                * and all three must be integers. Push the result of raising
+                * base to the exp power, reduced modulo mod. If we had base in
+                * register b, exp in register e, and mod in register m then this
+                * is conceptually equivalent to "lble^lm%", but it is implemented
+                * in a more efficient manner, and can handle arbritrarily large
+                * values for exp.
+                */
+               dc_triop(dc_modexp, dc_scale);
+               break;
+       case '^':       /* exponientiation of the top two stack elements */
+               dc_binop(dc_exp, dc_scale);
+               break;
+       case '<':
+               /* eval register named by peekc if
+                * less-than holds for top two stack elements
+                */
+               if (peekc == EOF)
+                       return DC_EOF_ERROR;
+               if ( (dc_cmpop() <  0) == (negcmp==0) )
+                       return DC_EVALREG;
+               return DC_EATONE;
+       case '=':
+               /* eval register named by peekc if
+                * equal-to holds for top two stack elements
+                */
+               if (peekc == EOF)
+                       return DC_EOF_ERROR;
+               if ( (dc_cmpop() == 0) == (negcmp==0) )
+                       return DC_EVALREG;
+               return DC_EATONE;
+       case '>':
+               /* eval register named by peekc if
+                * greater-than holds for top two stack elements
+                */
+               if (peekc == EOF)
+                       return DC_EOF_ERROR;
+               if ( (dc_cmpop() >  0) == (negcmp==0) )
+                       return DC_EVALREG;
+               return DC_EATONE;
+       case '?':       /* read a line from standard-input and eval it */
+               if (stdin_lookahead != EOF){
+                       ungetc(stdin_lookahead, stdin);
+                       stdin_lookahead = EOF;
+               }
+               datum = dc_readstring(stdin, '\n', '\n');
+               if (ferror(stdin))
+                       return DC_EOF_ERROR;
+               dc_push(datum);
+               return DC_EVALTOS;
+       case '[':       /* read to balancing ']' into a dc_str */
+               return DC_STR;
+       case '!':       /* read to newline and call system() on resulting string */
+               if (peekc == '<' || peekc == '=' || peekc == '>')
+                       return DC_NEGCMP;
+               return DC_SYSTEM;
+       case '#':       /* comment; skip remainder of current line */
+               return DC_COMMENT;
+
+       case 'a':       /* Convert top of stack to an ascii character. */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       char tmps;
+                       if (datum.dc_type == DC_NUMBER){
+                               tmps = (char) dc_num2int(datum.v.number, DC_TOSS);
+                       }else if (datum.dc_type == DC_STRING){
+                               tmps = *dc_str2charp(datum.v.string);
+                               dc_free_str(&datum.v.string);
+                       }else{
+                               dc_garbage("at top of stack", -1);
+                       }
+                       dc_push(dc_makestring(&tmps, 1));
+               }
+               break;
+       case 'c':       /* clear whole stack */
+               dc_clear_stack();
+               break;
+       case 'd':       /* duplicate the datum on the top of stack */
+               if (dc_top_of_stack(&datum) == DC_SUCCESS)
+                       dc_push(dc_dup(datum));
+               break;
+       case 'f':       /* print list of all stack items */
+               dc_printall(dc_obase);
+               break;
+       case 'i':       /* set input base to value on top of stack */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       tmpint = 0;
+                       if (datum.dc_type == DC_NUMBER)
+                               tmpint = dc_num2int(datum.v.number, DC_TOSS);
+                       if (2 <= tmpint  &&  tmpint <= DC_IBASE_MAX)
+                               dc_ibase = tmpint;
+                       else
+                               fprintf(stderr,
+                                               "%s: input base must be a number \
+between 2 and %d (inclusive)\n",
+                                               progname, DC_IBASE_MAX);
+               }
+               break;
+       case 'k':       /* set scale to value on top of stack */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       tmpint = -1;
+                       if (datum.dc_type == DC_NUMBER)
+                               tmpint = dc_num2int(datum.v.number, DC_TOSS);
+                       if ( ! (tmpint >= 0) )
+                               fprintf(stderr,
+                                               "%s: scale must be a nonnegative number\n",
+                                               progname);
+                       else
+                               dc_scale = tmpint;
+               }
+               break;
+       case 'l':       /* "load" -- push value on top of register stack named
+                                * by peekc onto top of evaluation stack; does not
+                                * modify the register stack
+                                */
+               if (peekc == EOF)
+                       return DC_EOF_ERROR;
+               if (dc_register_get(peekc, &datum) == DC_SUCCESS)
+                       dc_push(datum);
+               return DC_EATONE;
+       case 'n':       /* print the value popped off of top-of-stack;
+                                * do not add a trailing newline
+                                */
+               if (dc_pop(&datum) == DC_SUCCESS)
+                       dc_print(datum, dc_obase, DC_NONL, DC_TOSS);
+               break;
+       case 'o':       /* set output base to value on top of stack */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       tmpint = 0;
+                       if (datum.dc_type == DC_NUMBER)
+                               tmpint = dc_num2int(datum.v.number, DC_TOSS);
+                       if ( ! (tmpint > 1) )
+                               fprintf(stderr,
+                                               "%s: output base must be a number greater than 1\n",
+                                               progname);
+                       else
+                               dc_obase = tmpint;
+               }
+               break;
+       case 'p':       /* print the datum on the top of stack,
+                                * with a trailing newline
+                                */
+               if (dc_top_of_stack(&datum) == DC_SUCCESS)
+                       dc_print(datum, dc_obase, DC_WITHNL, DC_KEEP);
+               break;
+       case 'q':       /* quit two levels of evaluation, posibly exiting program */
+               unwind_depth = 1; /* the return below is the first level of returns */
+               unwind_noexit = DC_FALSE;
+               return DC_QUIT;
+       case 'r':       /* rotate (swap) the top two elements on the stack
+                                */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       dc_data datum2;
+                       int two_status;
+                       two_status = dc_pop(&datum2);
+                       dc_push(datum);
+                       if (two_status == DC_SUCCESS)
+                               dc_push(datum2);
+               }
+               break;
+       case 's':       /* "store" -- replace top of register stack named
+                                * by peekc with the value popped from the top
+                                * of the evaluation stack
+                                */
+               if (peekc == EOF)
+                       return DC_EOF_ERROR;
+               if (dc_pop(&datum) == DC_SUCCESS)
+                       dc_register_set(peekc, datum);
+               return DC_EATONE;
+       case 'v':       /* replace top of stack with its square root */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       dc_num tmpnum;
+                       if (datum.dc_type != DC_NUMBER){
+                               fprintf(stderr,
+                                               "%s: square root of nonnumeric attempted\n",
+                                               progname);
+                       }else if (dc_sqrt(datum.v.number, dc_scale, &tmpnum) == DC_SUCCESS){
+                               dc_free_num(&datum.v.number);
+                               datum.v.number = tmpnum;
+                               dc_push(datum);
+                       }
+               }
+               break;
+       case 'x':       /* eval the datum popped from top of stack */
+               return DC_EVALTOS;
+       case 'z':       /* push the current stack depth onto the top of stack */
+               dc_push(dc_int2data(dc_tell_stackdepth()));
+               break;
+
+       case 'I':       /* push the current input base onto the stack */
+               dc_push(dc_int2data(dc_ibase));
+               break;
+       case 'K':       /* push the current scale onto the stack */
+               dc_push(dc_int2data(dc_scale));
+               break;
+       case 'L':       /* pop a value off of register stack named by peekc
+                                * and push it onto the evaluation stack
+                                */
+               if (peekc == EOF)
+                       return DC_EOF_ERROR;
+               if (dc_register_pop(peekc, &datum) == DC_SUCCESS)
+                       dc_push(datum);
+               return DC_EATONE;
+       case 'O':       /* push the current output base onto the stack */
+               dc_push(dc_int2data(dc_obase));
+               break;
+       case 'P':
+               /* Pop the value off the top of a stack.  If it is
+                * a number, dump out the integer portion of its
+                * absolute value as a "base UCHAR_MAX+1" byte stream;
+                * if it is a string, just print it.
+                * In either case, do not append a trailing newline.
+                */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       if (datum.dc_type == DC_NUMBER)
+                               dc_dump_num(datum.v.number, DC_TOSS);
+                       else if (datum.dc_type == DC_STRING)
+                               dc_out_str(datum.v.string, DC_NONL, DC_TOSS);
+                       else
+                               dc_garbage("at top of stack", -1);
+               }
+               break;
+       case 'Q':       /* quit out of top-of-stack nested evals;
+                                * pops value from stack;
+                                * does not exit program (stops short if necessary)
+                                */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       unwind_depth = 0;
+                       unwind_noexit = DC_TRUE;
+                       if (datum.dc_type == DC_NUMBER)
+                               unwind_depth = dc_num2int(datum.v.number, DC_TOSS);
+                       if (unwind_depth-- > 0)
+                               return DC_QUIT;
+                       unwind_depth = 0;       /* paranoia */
+                       fprintf(stderr,
+                                       "%s: Q command requires a number >= 1\n",
+                                       progname);
+               }
+               break;
+#if 0
+       case 'R':       /* pop a value off of the evaluation stack,;
+                                * rotate the top remaining stack elements that many
+                                * places forward (negative numbers mean rotate
+                                * backward).
+                                */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       tmpint = 0;
+                       if (datum.dc_type == DC_NUMBER)
+                               tmpint = dc_num2int(datum.v.number, DC_TOSS);
+                       dc_stack_rotate(tmpint);
+               }
+               break;
+#endif
+       case 'S':       /* pop a value off of the evaluation stack
+                                * and push it onto the register stack named by peekc
+                                */
+               if (peekc == EOF)
+                       return DC_EOF_ERROR;
+               if (dc_pop(&datum) == DC_SUCCESS)
+                       dc_register_push(peekc, datum);
+               return DC_EATONE;
+       case 'X':       /* replace the number on top-of-stack with its scale factor */
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       tmpint = 0;
+                       if (datum.dc_type == DC_NUMBER)
+                               tmpint = dc_tell_scale(datum.v.number, DC_TOSS);
+                       dc_push(dc_int2data(tmpint));
+               }
+               break;
+       case 'Z':       /* replace the datum on the top-of-stack with its length */
+               if (dc_pop(&datum) == DC_SUCCESS)
+                       dc_push(dc_int2data(dc_tell_length(datum, DC_TOSS)));
+               break;
+
+       case ':':       /* store into array */
+               if (peekc == EOF)
+                       return DC_EOF_ERROR;
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       tmpint = -1;
+                       if (datum.dc_type == DC_NUMBER)
+                               tmpint = dc_num2int(datum.v.number, DC_TOSS);
+                       if (dc_pop(&datum) == DC_SUCCESS){
+                               if (tmpint < 0)
+                                       fprintf(stderr,
+                                                       "%s: array index must be a nonnegative integer\n",
+                                                       progname);
+                               else
+                                       dc_array_set(peekc, tmpint, datum);
+                       }
+               }
+               return DC_EATONE;
+       case ';':       /* retreive from array */
+               if (peekc == EOF)
+                       return DC_EOF_ERROR;
+               if (dc_pop(&datum) == DC_SUCCESS){
+                       tmpint = -1;
+                       if (datum.dc_type == DC_NUMBER)
+                               tmpint = dc_num2int(datum.v.number, DC_TOSS);
+                       if (tmpint < 0)
+                               fprintf(stderr,
+                                               "%s: array index must be a nonnegative integer\n",
+                                               progname);
+                       else
+                               dc_push(dc_array_get(peekc, tmpint));
+               }
+               return DC_EATONE;
+
+       default:        /* What did that user mean? */
+               fprintf(stderr, "%s: ", progname);
+               dc_show_id(stdout, c, " unimplemented\n");
+               break;
+       }
+       return DC_OKAY;
+}
+
+\f
+/* takes a string and evals it */
+int
+dc_evalstr DC_DECLARG((string))
+       dc_data *string DC_DECLEND
+{
+       const char *s;
+       const char *end;
+       const char *p;
+       size_t len;
+       int c;
+       int peekc;
+       int count;
+       int negcmp;
+       int next_negcmp = 0;
+       int tail_depth = 1; /* how much tail recursion is active */
+       dc_data evalstr;
+
+       if (string->dc_type != DC_STRING){
+               fprintf(stderr,
+                               "%s: eval called with non-string argument\n",
+                               progname);
+               return DC_OKAY;
+       }
+       interrupt_seen = 0;
+       s = dc_str2charp(string->v.string);
+       end = s + dc_strlen(string->v.string);
+       while (s < end && interrupt_seen==0){
+               c = *(const unsigned char *)s++;
+               peekc = EOF;
+               if (s < end)
+                       peekc = *(const unsigned char *)s;
+               negcmp = next_negcmp;
+               next_negcmp = 0;
+               switch (dc_func(c, peekc, negcmp)){
+               case DC_OKAY:
+                       break;
+               case DC_EATONE:
+                       if (peekc != EOF)
+                               ++s;
+                       break;
+               case DC_EVALREG:
+                       /*commands which return this guarantee that peekc!=EOF*/
+                       ++s;
+                       if (dc_register_get(peekc, &evalstr) != DC_SUCCESS)
+                               break;
+                       dc_push(evalstr);
+                       /*@fallthrough@*/
+               case DC_EVALTOS:
+                       /*skip trailing whitespace to assist tail-recursion detection*/
+                       while (s<end && (*s==' '||*s=='\t'||*s=='\n'||*s=='#')){
+                               if (*s++ == '#')
+                                       s = skip_past_eol(s, end);
+                       }
+                       if (dc_pop(&evalstr) == DC_SUCCESS){
+                               if (evalstr.dc_type == DC_NUMBER){
+                                       dc_push(evalstr);
+                                       return DC_OKAY;
+                               }else if (evalstr.dc_type != DC_STRING){
+                                       dc_garbage("at top of stack", -1);
+                               }else if (s == end){
+                                       /*handle tail recursion*/
+                                       dc_free_str(&string->v.string);
+                                       *string = evalstr;
+                                       s = dc_str2charp(string->v.string);
+                                       end = s + dc_strlen(string->v.string);
+                                       ++tail_depth;
+                               }else if (dc_eval_and_free_str(&evalstr) == DC_QUIT){
+                                       if (unwind_depth > 0){
+                                               --unwind_depth;
+                                               return DC_QUIT;
+                                       }
+                                       return DC_OKAY;
+                               }
+                       }
+                       break;
+               case DC_QUIT:
+                       if (unwind_depth >= tail_depth){
+                               unwind_depth -= tail_depth;
+                               return DC_QUIT;
+                       }
+                       return DC_OKAY;
+
+               case DC_INT:
+                       input_str_string = s - 1;
+                       dc_push(dc_getnum(input_str, dc_ibase, &peekc));
+                       s = input_str_string;
+                       if (peekc != EOF)
+                               --s;
+                       break;
+               case DC_STR:
+                       count = 1;
+                       for (p=s; p<end && count>0; ++p)
+                               if (*p == ']')
+                                       --count;
+                               else if (*p == '[')
+                                       ++count;
+                       len = (size_t) (p - s);
+                       dc_push(dc_makestring(s, len-1));
+                       s = p;
+                       break;
+               case DC_SYSTEM:
+                       s = dc_system(s);
+                       /*@fallthrough@*/
+               case DC_COMMENT:
+                       s = skip_past_eol(s, end);
+                       break;
+               case DC_NEGCMP:
+                       next_negcmp = 1;
+                       break;
+
+               case DC_EOF_ERROR:
+                       if (ferror(stdin)) {
+                               fprintf(stderr, "%s: ", progname);
+                               perror("error reading stdin");
+                               return DC_FAIL;
+                       }
+                       fprintf(stderr, "%s: unexpected EOS\n", progname);
+                       return DC_OKAY;
+               }
+       }
+       return DC_OKAY;
+}
+
+\f
+/* This is the main function of the whole DC program.
+ * Reads the file described by fp, calls dc_func to do
+ * the dirty work, and takes care of dc_func's shortcomings.
+ */
+int
+dc_evalfile DC_DECLARG((fp))
+       FILE *fp DC_DECLEND
+{
+       int c;
+       int peekc;
+       int negcmp;
+       int next_negcmp = 0;
+       dc_data datum;
+
+       signal(SIGINT, dc_trap_interrupt);
+       stdin_lookahead = EOF;
+       for (c=getc(fp); c!=EOF; c=peekc){
+               peekc = getc(fp);
+               /*
+                * The following if() is the only place where ``stdin_lookahead''
+                * might be set to other than EOF:
+                */
+               if (fp == stdin)
+                       stdin_lookahead = peekc;
+               /*
+                * In the switch(), cases which naturally update peekc
+                * (unconditionally) do not have to update or reference
+                * stdin_lookahead; other functions use the predicate:
+                *    stdin_lookahead != peekc  &&  fp == stdin
+                * to recognize the case where:
+                *   a) stdin_lookahead == EOF (stdin and peekc are not in sync)
+                *   b) peekc != EOF (resync is possible)
+                *   c) fp == stdin (resync is relevant)
+                * The whole stdin_lookahead complication arises because the
+                * '?' command may be invoked from an arbritrarily deeply
+                * nested dc_evalstr(), '?' reads exclusively from stdin,
+                * and this winds up making peekc invalid when fp==stdin.
+                */
+               negcmp = next_negcmp;
+               next_negcmp = 0;
+               switch (dc_func(c, peekc, negcmp)){
+               case DC_OKAY:
+                       if (stdin_lookahead != peekc  &&  fp == stdin)
+                               peekc = getc(fp);
+                       break;
+               case DC_EATONE:
+                       peekc = getc(fp);
+                       break;
+               case DC_EVALREG:
+                       /*commands which send us here shall guarantee that peekc!=EOF*/
+                       c = peekc;
+                       peekc = getc(fp);
+                       stdin_lookahead = peekc;
+                       if (dc_register_get(c, &datum) != DC_SUCCESS)
+                               break;
+                       dc_push(datum);
+                       /*@fallthrough@*/
+               case DC_EVALTOS:
+                       if (stdin_lookahead != peekc  &&  fp == stdin)
+                               peekc = getc(fp);
+                       if (dc_pop(&datum) == DC_SUCCESS){
+                               if (datum.dc_type == DC_NUMBER){
+                                       dc_push(datum);
+                               }else if (datum.dc_type == DC_STRING){
+                                       if (dc_eval_and_free_str(&datum) == DC_QUIT){
+                                               if (unwind_noexit != DC_TRUE)
+                                                       return DC_SUCCESS;
+                                               fprintf(stderr, "%s: Q command argument exceeded \
+string execution depth\n", progname);
+                                       }
+                               }else{
+                                       dc_garbage("at top of stack", -1);
+                               }
+                       }
+                       break;
+               case DC_QUIT:
+                       if (unwind_noexit != DC_TRUE)
+                               return DC_SUCCESS;
+                       fprintf(stderr,
+                                       "%s: Q command argument exceeded string execution depth\n",
+                                       progname);
+                       if (stdin_lookahead != peekc  &&  fp == stdin)
+                               peekc = getc(fp);
+                       break;
+
+               case DC_INT:
+                       input_fil_fp = fp;
+                       input_pushback = c;
+                       ungetc(peekc, fp);
+                       dc_push(dc_getnum(input_fil, dc_ibase, &peekc));
+                       if (ferror(fp))
+                               goto error_fail;
+                       break;
+               case DC_STR:
+                       ungetc(peekc, fp);
+                       datum = dc_readstring(fp, '[', ']');
+                       if (ferror(fp))
+                               goto error_fail;
+                       dc_push(datum);
+                       peekc = getc(fp);
+                       break;
+               case DC_SYSTEM:
+                       ungetc(peekc, fp);
+                       datum = dc_readstring(stdin, '\n', '\n');
+                       if (ferror(stdin))
+                               goto error_fail;
+                       (void)dc_system(dc_str2charp(datum.v.string));
+                       dc_free_str(&datum.v.string);
+                       peekc = getc(fp);
+                       break;
+               case DC_COMMENT:
+                       while (peekc!=EOF && peekc!='\n')
+                               peekc = getc(fp);
+                       if (peekc != EOF)
+                               peekc = getc(fp);
+                       break;
+               case DC_NEGCMP:
+                       next_negcmp = 1;
+                       break;
+
+               case DC_EOF_ERROR:
+                       if (ferror(fp))
+                               goto error_fail;
+                       fprintf(stderr, "%s: unexpected EOF\n", progname);
+                       return DC_FAIL;
+               }
+       }
+       if (!ferror(fp))
+               return DC_SUCCESS;
+
+error_fail:
+       fprintf(stderr, "%s: ", progname);
+       perror("error reading input");
+       return DC_FAIL;
+}
+
+\f
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 4
+ * End:
+ * vi: set ts=4 :
+ */
diff --git a/dc/misc.c b/dc/misc.c
new file mode 100644 (file)
index 0000000..f2388b0
--- /dev/null
+++ b/dc/misc.c
@@ -0,0 +1,188 @@
+/* 
+ * misc. functions for the "dc" Desk Calculator language.
+ *
+ * Copyright (C) 1994, 1997, 1998, 2000, 2006 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, you can either send email to this
+ * program's author (see below) or write to:
+ *   The Free Software Foundation, Inc.
+ *   51 Franklin Street, Fifth Floor
+ *   Boston, MA 02110-1301  USA
+ */
+
+/* This module contains miscellaneous functions that have no
+ * special knowledge of any private data structures.
+ * They could each be moved to their own separate modules,
+ * but are aggregated here as a matter of convenience.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif
+#include <ctype.h>
+#ifndef isgraph
+# ifndef HAVE_ISGRAPH
+#  define isgraph isprint
+# endif
+#endif
+#include <getopt.h>
+#include "dc.h"
+#include "dc-proto.h"
+
+#ifndef EXIT_FAILURE   /* C89 <stdlib.h> */
+# define EXIT_FAILURE  1
+#endif
+
+\f
+/* print an "out of memory" diagnostic and exit program */
+void
+dc_memfail DC_DECLVOID()
+{
+       fprintf(stderr, "%s: out of memory\n", progname);
+       exit(EXIT_FAILURE);
+}
+
+/* malloc or die */
+void *
+dc_malloc DC_DECLARG((len))
+       size_t len DC_DECLEND
+{
+       void *result = malloc(len);
+
+       if (result == NULL)
+               dc_memfail();
+       return result;
+}
+
+\f
+/* print the id in a human-understandable form
+ *  fp is the output stream to place the output on
+ *  id is the name of the register (or command) to be printed
+ *  suffix is a modifier (such as "stack") to be printed
+ */
+void
+dc_show_id DC_DECLARG((fp, id, suffix))
+       FILE *fp DC_DECLSEP
+       int id DC_DECLSEP
+       const char *suffix DC_DECLEND
+{
+       if (isgraph(id))
+               fprintf(fp, "'%c' (%#o)%s", (unsigned int) id, id, suffix);
+       else
+               fprintf(fp, "%#o%s", (unsigned int) id, suffix);
+}
+
+\f
+/* report that corrupt data has been detected;
+ * use the msg and regid (if nonnegative) to give information
+ * about where the garbage was found,
+ *
+ * will abort() so that a debugger might be used to help find
+ * the bug
+ */
+/* If this routine is called, then there is a bug in the code;
+ * i.e. it is _not_ a data or user error
+ */
+void
+dc_garbage DC_DECLARG((msg, regid))
+       const char *msg DC_DECLSEP
+       int regid DC_DECLEND
+{
+       if (regid < 0) {
+               fprintf(stderr, "%s: garbage %s\n", progname, msg);
+       } else {
+               fprintf(stderr, "%s:%s register ", progname, msg);
+               dc_show_id(stderr, regid, " is garbage\n");
+       }
+       abort();
+}
+
+\f
+/* call system() with the passed string;
+ * if the string contains a newline, terminate the string
+ * there before calling system.
+ * Return a pointer to the first unused character in the string
+ * (i.e. past the '\n' if there was one, to the '\0' otherwise).
+ */
+const char *
+dc_system DC_DECLARG((s))
+       const char *s DC_DECLEND
+{
+       const char *p;
+       char *tmpstr;
+       size_t len;
+
+       p = strchr(s, '\n');
+       if (p != NULL) {
+               len = (size_t) (p - s);
+               tmpstr = dc_malloc(len + 1);
+               strncpy(tmpstr, s, len);
+               tmpstr[len] = '\0';
+               system(tmpstr);
+               free(tmpstr);
+               return p + 1;
+       }
+       system(s);
+       return s + strlen(s);
+}
+
+\f
+/* print out the indicated value */
+void
+dc_print DC_DECLARG((value, obase, newline_p, discard_p))
+       dc_data value DC_DECLSEP
+       int obase DC_DECLSEP
+       dc_newline newline_p DC_DECLSEP
+       dc_discard discard_p DC_DECLEND
+{
+       if (value.dc_type == DC_NUMBER) {
+               dc_out_num(value.v.number, obase, newline_p, discard_p);
+       } else if (value.dc_type == DC_STRING) {
+               dc_out_str(value.v.string, newline_p, discard_p);
+       } else {
+               dc_garbage("in data being printed", -1);
+       }
+}
+
+/* return a duplicate of the passed value, regardless of type */
+dc_data
+dc_dup DC_DECLARG((value))
+       dc_data value DC_DECLEND
+{
+       if (value.dc_type!=DC_NUMBER && value.dc_type!=DC_STRING)
+               dc_garbage("in value being duplicated", -1);
+       if (value.dc_type == DC_NUMBER)
+               return dc_dup_num(value.v.number);
+       /*else*/
+       return dc_dup_str(value.v.string);
+}
+
+\f
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 4
+ * End:
+ * vi: set ts=4 :
+ */
diff --git a/dc/numeric.c b/dc/numeric.c
new file mode 100644 (file)
index 0000000..8e5e70f
--- /dev/null
@@ -0,0 +1,676 @@
+/* 
+ * interface dc to the bc numeric routines
+ *
+ * Copyright (C) 1994, 1997, 1998, 2000, 2005 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, you can write to:
+ *   The Free Software Foundation, Inc.
+ *   51 Franklin Street, Fifth Floor
+ *   Boston, MA 02110-1301  USA
+ */
+
+/* This should be the only module that knows the internals of type dc_num */
+/* In this particular implementation we just slather out some glue and
+ * make use of bc's numeric routines.
+ */
+
+/* make all the header files see that these are really the same thing;
+ * this is acceptable because everywhere else dc_number is just referenced
+ * as a pointer-to-incomplete-structure type
+ */
+#define dc_number bc_struct
+
+#include "config.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+#ifndef UCHAR_MAX
+# define UCHAR_MAX ((unsigned char)~0)
+#endif
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#else
+  extern int errno;
+#endif
+
+#include "number.h"
+#include "dc.h"
+#include "dc-proto.h"
+
+#ifdef __GNUC__
+# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__-0 >= 7) 
+#  define ATTRIB(x) __attribute__(x)
+# endif
+#endif
+#ifndef ATTRIB
+# define ATTRIB(x)
+#endif
+
+/* Forward prototype */
+static void out_char (int);
+
+/* there is no POSIX standard for dc, so we'll take the GNU definitions */
+int std_only = FALSE;
+
+/* convert an opaque dc_num into a real bc_num */
+/* by a freak accident, these are now no-op mappings,
+ * but leave the notation here in case that changes later
+ * */
+#define CastNum(x)             (x)
+#define CastNumPtr(x)  (x)
+
+/* add two dc_nums, place into *result;
+ * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
+ */
+int
+dc_add DC_DECLARG((a, b, kscale, result))
+       dc_num a DC_DECLSEP
+       dc_num b DC_DECLSEP
+       int kscale ATTRIB((unused)) DC_DECLSEP
+       dc_num *result DC_DECLEND
+{
+       bc_init_num(CastNumPtr(result));
+       bc_add(CastNum(a), CastNum(b), CastNumPtr(result), 0);
+       return DC_SUCCESS;
+}
+
+/* subtract two dc_nums, place into *result;
+ * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
+ */
+int
+dc_sub DC_DECLARG((a, b, kscale, result))
+       dc_num a DC_DECLSEP
+       dc_num b DC_DECLSEP
+       int kscale ATTRIB((unused)) DC_DECLSEP
+       dc_num *result DC_DECLEND
+{
+       bc_init_num(CastNumPtr(result));
+       bc_sub(CastNum(a), CastNum(b), CastNumPtr(result), 0);
+       return DC_SUCCESS;
+}
+
+/* multiply two dc_nums, place into *result;
+ * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
+ */
+int
+dc_mul DC_DECLARG((a, b, kscale, result))
+       dc_num a DC_DECLSEP
+       dc_num b DC_DECLSEP
+       int kscale DC_DECLSEP
+       dc_num *result DC_DECLEND
+{
+       bc_init_num(CastNumPtr(result));
+       bc_multiply(CastNum(a), CastNum(b), CastNumPtr(result), kscale);
+       return DC_SUCCESS;
+}
+
+/* divide two dc_nums, place into *result;
+ * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
+ */
+int
+dc_div DC_DECLARG((a, b, kscale, result))
+       dc_num a DC_DECLSEP
+       dc_num b DC_DECLSEP
+       int kscale DC_DECLSEP
+       dc_num *result DC_DECLEND
+{
+       bc_init_num(CastNumPtr(result));
+       if (bc_divide(CastNum(a), CastNum(b), CastNumPtr(result), kscale)){
+               fprintf(stderr, "%s: divide by zero\n", progname);
+               return DC_DOMAIN_ERROR;
+       }
+       return DC_SUCCESS;
+}
+
+/* divide two dc_nums, place quotient into *quotient and remainder
+ * into *remainder;
+ * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
+ */
+int
+dc_divrem DC_DECLARG((a, b, kscale, quotient, remainder))
+       dc_num a DC_DECLSEP
+       dc_num b DC_DECLSEP
+       int kscale DC_DECLSEP
+       dc_num *quotient DC_DECLSEP
+       dc_num *remainder DC_DECLEND
+{
+       bc_init_num(CastNumPtr(quotient));
+       bc_init_num(CastNumPtr(remainder));
+       if (bc_divmod(CastNum(a), CastNum(b),
+                                               CastNumPtr(quotient), CastNumPtr(remainder), kscale)){
+               fprintf(stderr, "%s: divide by zero\n", progname);
+               return DC_DOMAIN_ERROR;
+       }
+       return DC_SUCCESS;
+}
+
+/* place the reminder of dividing a by b into *result;
+ * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
+ */
+int
+dc_rem DC_DECLARG((a, b, kscale, result))
+       dc_num a DC_DECLSEP
+       dc_num b DC_DECLSEP
+       int kscale DC_DECLSEP
+       dc_num *result DC_DECLEND
+{
+       bc_init_num(CastNumPtr(result));
+       if (bc_modulo(CastNum(a), CastNum(b), CastNumPtr(result), kscale)){
+               fprintf(stderr, "%s: remainder by zero\n", progname);
+               return DC_DOMAIN_ERROR;
+       }
+       return DC_SUCCESS;
+}
+
+int
+dc_modexp DC_DECLARG((base, expo, mod, kscale, result))
+       dc_num base DC_DECLSEP
+       dc_num expo DC_DECLSEP
+       dc_num mod DC_DECLSEP
+       int kscale DC_DECLSEP
+       dc_num *result DC_DECLEND
+{
+       bc_init_num(CastNumPtr(result));
+       if (bc_raisemod(CastNum(base), CastNum(expo), CastNum(mod),
+                                       CastNumPtr(result), kscale)){
+               if (bc_is_zero(CastNum(mod)))
+                       fprintf(stderr, "%s: remainder by zero\n", progname);
+               return DC_DOMAIN_ERROR;
+       }
+       return DC_SUCCESS;
+}
+
+/* place the result of exponentiationg a by b into *result;
+ * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
+ */
+int
+dc_exp DC_DECLARG((a, b, kscale, result))
+       dc_num a DC_DECLSEP
+       dc_num b DC_DECLSEP
+       int kscale DC_DECLSEP
+       dc_num *result DC_DECLEND
+{
+       bc_init_num(CastNumPtr(result));
+       bc_raise(CastNum(a), CastNum(b), CastNumPtr(result), kscale);
+       return DC_SUCCESS;
+}
+
+/* take the square root of the value, place into *result;
+ * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error
+ */
+int
+dc_sqrt DC_DECLARG((value, kscale, result))
+       dc_num value DC_DECLSEP
+       int kscale DC_DECLSEP
+       dc_num *result DC_DECLEND
+{
+       bc_num tmp;
+
+       tmp = bc_copy_num(CastNum(value));
+       if (!bc_sqrt(&tmp, kscale)){
+               fprintf(stderr, "%s: square root of negative number\n", progname);
+               bc_free_num(&tmp);
+               return DC_DOMAIN_ERROR;
+       }
+       *(CastNumPtr(result)) = tmp;
+       return DC_SUCCESS;
+}
+
+/* compare dc_nums a and b;
+ *  return a negative value if a < b;
+ *  return a positive value if a > b;
+ *  return zero value if a == b
+ */
+int
+dc_compare DC_DECLARG((a, b))
+       dc_num a DC_DECLSEP
+       dc_num b DC_DECLEND
+{
+       return bc_compare(CastNum(a), CastNum(b));
+}
+\f
+/* attempt to convert a dc_num to its corresponding int value
+ * If discard_p is DC_TOSS then deallocate the value after use.
+ */
+int
+dc_num2int DC_DECLARG((value, discard_p))
+       dc_num value DC_DECLSEP
+       dc_discard discard_p DC_DECLEND
+{
+       long result;
+
+       result = bc_num2long(CastNum(value));
+       if (result == 0 && !bc_is_zero(CastNum(value))) {
+               fprintf(stderr, "%s: value overflows simple integer; punting...\n",
+                               progname);
+               result = -1; /* more appropriate for dc's purposes */
+       }
+       if (discard_p == DC_TOSS)
+               dc_free_num(&value);
+       return (int)result;
+}
+
+/* convert a C integer value into a dc_num */
+/* For convenience of the caller, package the dc_num
+ * into a dc_data result.
+ */
+dc_data
+dc_int2data DC_DECLARG((value))
+       int value DC_DECLEND
+{
+       dc_data result;
+
+       bc_init_num(CastNumPtr(&result.v.number));
+       bc_int2num(CastNumPtr(&result.v.number), value);
+       result.dc_type = DC_NUMBER;
+       return result;
+}
+
+/* get a dc_num from some input stream;
+ *  input is a function which knows how to read the desired input stream
+ *  ibase is the input base (2<=ibase<=DC_IBASE_MAX)
+ *  *readahead will be set to the readahead character consumed while
+ *   looking for the end-of-number
+ */
+/* For convenience of the caller, package the dc_num
+ * into a dc_data result.
+ */
+dc_data
+dc_getnum DC_DECLARG((input, ibase, readahead))
+       int (*input) DC_PROTO((void)) DC_DECLSEP
+       int ibase DC_DECLSEP
+       int *readahead DC_DECLEND
+{
+       bc_num  base;
+       bc_num  result;
+       bc_num  build;
+       bc_num  tmp;
+       bc_num  divisor;
+       dc_data full_result;
+       int             negative = 0;
+       int             digit;
+       int             decimal;
+       int             c;
+
+       bc_init_num(&tmp);
+       bc_init_num(&build);
+       bc_init_num(&base);
+       result = bc_copy_num(_zero_);
+       bc_int2num(&base, ibase);
+       c = (*input)();
+       while (isspace(c))
+               c = (*input)();
+       if (c == '_' || c == '-'){
+               negative = c;
+               c = (*input)();
+       }else if (c == '+'){
+               c = (*input)();
+       }
+       while (isspace(c))
+               c = (*input)();
+       for (;;){
+               if (isdigit(c))
+                       digit = c - '0';
+               else if ('A' <= c && c <= 'F')
+                       digit = 10 + c - 'A';
+               else
+                       break;
+               c = (*input)();
+               bc_int2num(&tmp, digit);
+               bc_multiply(result, base, &result, 0);
+               bc_add(result, tmp, &result, 0);
+       }
+       if (c == '.'){
+               bc_free_num(&build);
+               bc_free_num(&tmp);
+               divisor = bc_copy_num(_one_);
+               build = bc_copy_num(_zero_);
+               decimal = 0;
+               for (;;){
+                       c = (*input)();
+                       if (isdigit(c))
+                               digit = c - '0';
+                       else if ('A' <= c && c <= 'F')
+                               digit = 10 + c - 'A';
+                       else
+                               break;
+                       bc_int2num(&tmp, digit);
+                       bc_multiply(build, base, &build, 0);
+                       bc_add(build, tmp, &build, 0);
+                       bc_multiply(divisor, base, &divisor, 0);
+                       ++decimal;
+               }
+               bc_divide(build, divisor, &build, decimal);
+               bc_add(result, build, &result, 0);
+       }
+       /* Final work. */
+       if (negative)
+               bc_sub(_zero_, result, &result, 0);
+
+       bc_free_num(&tmp);
+       bc_free_num(&build);
+       bc_free_num(&base);
+       if (readahead)
+               *readahead = c;
+       *CastNumPtr(&full_result.v.number) = result;
+       full_result.dc_type = DC_NUMBER;
+       return full_result;
+}
+
+\f
+/* Return the "length" of the number, ignoring *all* leading zeros,
+ * (including those to the right of the radix point!)
+ */
+int
+dc_numlen DC_DECLARG((value))
+       dc_num value DC_DECLEND
+{
+       /* XXX warning: unholy coziness with the internals of a bc_num! */
+       bc_num num = CastNum(value);
+       char *p = num->n_value;
+       int i = num->n_len + num->n_scale;
+
+       while (1<i && *p=='\0')
+               --i, ++p;
+       return i;
+}
+
+/* return the scale factor of the passed dc_num
+ * If discard_p is DC_TOSS then deallocate the value after use.
+ */
+int
+dc_tell_scale DC_DECLARG((value, discard_p))
+       dc_num value DC_DECLSEP
+       dc_discard discard_p DC_DECLEND
+{
+       int kscale;
+
+       kscale = CastNum(value)->n_scale;
+       if (discard_p == DC_TOSS)
+               dc_free_num(&value);
+       return kscale;
+}
+
+\f
+/* initialize the math subsystem */
+void
+dc_math_init DC_DECLVOID()
+{
+       bc_init_numbers();
+}
+\f
+/* print out a dc_num in output base obase to stdout;
+ * if newline_p is DC_WITHNL, terminate output with a '\n';
+ * if discard_p is DC_TOSS then deallocate the value after use
+ */
+void
+dc_out_num DC_DECLARG((value, obase, newline_p, discard_p))
+       dc_num value DC_DECLSEP
+       int obase DC_DECLSEP
+       dc_newline newline_p DC_DECLSEP
+       dc_discard discard_p DC_DECLEND
+{
+       out_char('\0'); /* clear the column counter */
+       bc_out_num(CastNum(value), obase, out_char, 0);
+       if (newline_p == DC_WITHNL)
+               putchar ('\n');
+       if (discard_p == DC_TOSS)
+               dc_free_num(&value);
+}
+
+/* dump out the absolute value of the integer part of a
+ * dc_num as a byte stream, without any line wrapping;
+ * if discard_p is DC_TOSS then deallocate the value after use
+ */
+void
+dc_dump_num DC_DECLARG((dcvalue, discard_p))
+       dc_num dcvalue DC_DECLSEP
+       dc_discard discard_p DC_DECLEND
+{
+       struct digit_stack { int digit; struct digit_stack *link;};
+       struct digit_stack *top_of_stack = NULL;
+       struct digit_stack *cur;
+       struct digit_stack *next;
+       bc_num value;
+       bc_num obase;
+       bc_num digit;
+
+       bc_init_num(&value);
+       bc_init_num(&obase);
+       bc_init_num(&digit);
+
+       /* we only handle the integer portion: */
+       bc_divide(CastNum(dcvalue), _one_, &value, 0);
+       /* we only handle the absolute value: */
+       value->n_sign = PLUS;
+       /* we're done with the dcvalue parameter: */
+       if (discard_p == DC_TOSS)
+               dc_free_num(&dcvalue);
+
+       bc_int2num(&obase, 1+UCHAR_MAX);
+       do {
+               (void) bc_divmod(value, obase, &value, &digit, 0);
+               cur = dc_malloc(sizeof *cur);
+               cur->digit = (int)bc_num2long(digit);
+               cur->link = top_of_stack;
+               top_of_stack = cur;
+       } while (!bc_is_zero(value));
+
+       for (cur=top_of_stack; cur; cur=next) {
+               putchar(cur->digit);
+               next = cur->link;
+               free(cur);
+       }
+
+       bc_free_num(&digit);
+       bc_free_num(&obase);
+       bc_free_num(&value);
+}
+\f
+/* deallocate an instance of a dc_num */
+void
+dc_free_num DC_DECLARG((value))
+       dc_num *value DC_DECLEND
+{
+       bc_free_num(CastNumPtr(value));
+}
+
+/* return a duplicate of the number in the passed value */
+/* The mismatched data types forces the caller to deal with
+ * bad dc_type'd dc_data values, and makes it more convenient
+ * for the caller to not have to do the grunge work of setting
+ * up a dc_type result.
+ */
+dc_data
+dc_dup_num DC_DECLARG((value))
+       dc_num value DC_DECLEND
+{
+       dc_data result;
+
+       ++CastNum(value)->n_refs;
+       result.v.number = value;
+       result.dc_type = DC_NUMBER;
+       return result;
+}
+
+\f
+
+/*---------------------------------------------------------------------------\
+| The rest of this file consists of stubs for bc routines called by numeric.c|
+| so as to minimize the amount of bc code needed to build dc.                |
+| The bulk of the code was just lifted straight out of the bc source.        |
+\---------------------------------------------------------------------------*/
+
+#ifdef HAVE_STDARG_H
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+#ifndef HAVE_STRTOL
+/* Maintain some of the error checking of a real strtol() on
+ * ancient systems that lack one, but punting on the niceties
+ * of supporting bases other than 10 and overflow checking.
+ */
+long
+strtol(const char *s, char **end, int base)
+{
+       int sign = 1;
+       long result = 0;
+
+       for (;; ++s) {
+               if (*s == '-')
+                       sign = -sign;
+               else if (*s != '+' && !isspace(*s))
+                       break;
+       }
+       while (isdigit(*s))
+               result = 10*result + (*s++ - '0');
+       *end = s;
+       return result * sign;
+}
+#endif /*!HAVE_STRTOL*/
+
+
+static int out_col = 0;
+static int line_max = -1;      /* negative means "need to check environment" */
+#define DEFAULT_LINE_MAX 70
+
+static void
+set_line_max_from_environment(void)
+{
+       const char *env_line_len = getenv("DC_LINE_LENGTH");
+       line_max = DEFAULT_LINE_MAX;
+       errno = 0;
+       if (env_line_len) {
+               char *endptr;
+               long proposed_line_len = strtol(env_line_len, &endptr, 0);
+               line_max = (int)proposed_line_len;
+
+               /* silently enforce sanity */
+               while (isspace(*endptr))
+                       ++endptr;
+               if (*endptr || errno || line_max != proposed_line_len
+                                       || line_max < 0 || line_max == 1)
+                       line_max = DEFAULT_LINE_MAX;
+       }
+}
+
+/* Output routines: Write a character CH to the standard output.
+   It keeps track of the number of characters output and may
+   break the output with a "\<cr>". */
+
+static void
+out_char (ch)
+       int ch;
+{
+       if (ch == '\0') {
+               out_col = 0;
+       } else {
+               if (line_max < 0)
+                       set_line_max_from_environment();
+               if (++out_col >= line_max && line_max != 0) {
+                       putchar ('\\');
+                       putchar ('\n');
+                       out_col = 1;
+               }
+               putchar(ch);
+       }
+}
+
+/* Malloc could not get enough memory. */
+
+void
+out_of_memory()
+{
+       dc_memfail();
+}
+
+/* Runtime error --- will print a message and stop the machine. */
+
+#ifdef HAVE_STDARG_H
+#ifdef __STDC__
+void
+rt_error (char *mesg, ...)
+#else
+void
+rt_error (mesg)
+       char *mesg;
+#endif
+#else
+void
+rt_error (mesg, va_alist)
+       char *mesg;
+#endif
+{
+       va_list args;
+
+       fprintf (stderr, "Runtime error: ");
+#ifdef HAVE_STDARG_H
+       va_start (args, mesg);
+#else
+       va_start (args);
+#endif
+       vfprintf (stderr, mesg, args);
+       va_end (args);
+       fprintf (stderr, "\n");
+}
+
+
+/* A runtime warning tells of some action taken by the processor that
+   may change the program execution but was not enough of a problem
+   to stop the execution. */
+
+#ifdef HAVE_STDARG_H
+#ifdef __STDC__
+void
+rt_warn (char *mesg, ...)
+#else
+void
+rt_warn (mesg)
+       char *mesg;
+#endif
+#else
+void
+rt_warn (mesg, va_alist)
+       char *mesg;
+#endif
+{
+       va_list args;
+
+       fprintf (stderr, "Runtime warning: ");
+#ifdef HAVE_STDARG_H
+       va_start (args, mesg);
+#else
+       va_start (args);
+#endif
+       vfprintf (stderr, mesg, args);
+       va_end (args);
+       fprintf (stderr, "\n");
+}
+
+\f
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 4
+ * End:
+ * vi: set ts=4 :
+ */
diff --git a/dc/stack.c b/dc/stack.c
new file mode 100644 (file)
index 0000000..0730e9c
--- /dev/null
@@ -0,0 +1,506 @@
+/* 
+ * implement stack functions for dc
+ *
+ * Copyright (C) 1994, 1997, 1998, 2000, 2005, 2006 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, you can either send email to this
+ * program's author (see below) or write to:
+ *
+ *    The Free Software Foundation, Inc.
+ *    51 Franklin Street, Fifth Floor
+ *    Boston, MA 02110-1301  USA
+ */
+
+/* This module is the only one that knows what stacks (both the
+ * regular evaluation stack and the named register stacks)
+ * look like.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#include "dc.h"
+#include "dc-proto.h"
+#include "dc-regdef.h"
+
+/* an oft-used error message: */
+#define Empty_Stack    fprintf(stderr, "%s: stack empty\n", progname)
+
+
+/* simple linked-list implementation suffices: */
+struct dc_list {
+       dc_data value;
+       struct dc_array *array; /* opaque */
+       struct dc_list *link;
+};
+typedef struct dc_list dc_list;
+
+/* the anonymous evaluation stack */
+static dc_list *dc_stack=NULL;
+
+/* the named register stacks */
+typedef dc_list *dc_listp;
+static dc_listp dc_register[DC_REGCOUNT];
+
+\f
+/* allocate a new dc_list item */
+static dc_list *
+dc_alloc DC_DECLVOID()
+{
+       dc_list *result;
+
+       result = dc_malloc(sizeof *result);
+       result->value.dc_type = DC_UNINITIALIZED;
+       result->array = NULL;
+       result->link = NULL;
+       return result;
+}
+
+\f
+/* check that there are two numbers on top of the stack,
+ * then call op with the popped numbers.  Construct a dc_data
+ * value from the dc_num returned by op and push it
+ * on the stack.
+ * If the op call doesn't return DC_SUCCESS, then leave the stack
+ * unmodified.
+ */
+void
+dc_binop DC_DECLARG((op, kscale))
+       int (*op)DC_PROTO((dc_num, dc_num, int, dc_num *)) DC_DECLSEP
+       int kscale DC_DECLEND
+{
+       dc_data a;
+       dc_data b;
+       dc_data r;
+
+       if (dc_stack == NULL  ||  dc_stack->link == NULL){
+               Empty_Stack;
+               return;
+       }
+       if (dc_stack->value.dc_type!=DC_NUMBER
+                       || dc_stack->link->value.dc_type!=DC_NUMBER){
+               fprintf(stderr, "%s: non-numeric value\n", progname);
+               return;
+       }
+       (void)dc_pop(&b);
+       (void)dc_pop(&a);
+       if ((*op)(a.v.number, b.v.number, kscale, &r.v.number) == DC_SUCCESS){
+               r.dc_type = DC_NUMBER;
+               dc_push(r);
+               dc_free_num(&a.v.number);
+               dc_free_num(&b.v.number);
+       }else{
+               /* op failed; restore the stack */
+               dc_push(a);
+               dc_push(b);
+       }
+}
+
+/* check that there are two numbers on top of the stack,
+ * then call op with the popped numbers.  Construct two dc_data
+ * values from the dc_num's returned by op and push them
+ * on the stack.
+ * If the op call doesn't return DC_SUCCESS, then leave the stack
+ * unmodified.
+ */
+void
+dc_binop2 DC_DECLARG((op, kscale))
+       int (*op)DC_PROTO((dc_num, dc_num, int, dc_num *, dc_num *)) DC_DECLSEP
+       int kscale DC_DECLEND
+{
+       dc_data a;
+       dc_data b;
+       dc_data r1;
+       dc_data r2;
+
+       if (dc_stack == NULL  ||  dc_stack->link == NULL){
+               Empty_Stack;
+               return;
+       }
+       if (dc_stack->value.dc_type!=DC_NUMBER
+                       || dc_stack->link->value.dc_type!=DC_NUMBER){
+               fprintf(stderr, "%s: non-numeric value\n", progname);
+               return;
+       }
+       (void)dc_pop(&b);
+       (void)dc_pop(&a);
+       if ((*op)(a.v.number, b.v.number, kscale,
+                                                               &r1.v.number, &r2.v.number) == DC_SUCCESS){
+               r1.dc_type = DC_NUMBER;
+               dc_push(r1);
+               r2.dc_type = DC_NUMBER;
+               dc_push(r2);
+               dc_free_num(&a.v.number);
+               dc_free_num(&b.v.number);
+       }else{
+               /* op failed; restore the stack */
+               dc_push(a);
+               dc_push(b);
+       }
+}
+
+/* check that there are two numbers on top of the stack,
+ * then call dc_compare with the popped numbers.
+ * Return negative, zero, or positive based on the ordering
+ * of the two numbers.
+ */
+int
+dc_cmpop DC_DECLVOID()
+{
+       int result;
+       dc_data a;
+       dc_data b;
+
+       if (dc_stack == NULL  ||  dc_stack->link == NULL){
+               Empty_Stack;
+               return 0;
+       }
+       if (dc_stack->value.dc_type!=DC_NUMBER
+                       || dc_stack->link->value.dc_type!=DC_NUMBER){
+               fprintf(stderr, "%s: non-numeric value\n", progname);
+               return 0;
+       }
+       (void)dc_pop(&b);
+       (void)dc_pop(&a);
+       result = dc_compare(b.v.number, a.v.number);
+       dc_free_num(&a.v.number);
+       dc_free_num(&b.v.number);
+       return result;
+}
+
+/* check that there are three numbers on top of the stack,
+ * then call op with the popped numbers.  Construct a dc_data
+ * value from the dc_num returned by op and push it
+ * on the stack.
+ * If the op call doesn't return DC_SUCCESS, then leave the stack
+ * unmodified.
+ */
+void
+dc_triop DC_DECLARG((op, kscale))
+       int (*op)DC_PROTO((dc_num, dc_num, dc_num, int, dc_num *)) DC_DECLSEP
+       int kscale DC_DECLEND
+{
+       dc_data a;
+       dc_data b;
+       dc_data c;
+       dc_data r;
+
+       if (dc_stack == NULL
+                       || dc_stack->link == NULL
+                       || dc_stack->link->link == NULL){
+               Empty_Stack;
+               return;
+       }
+       if (dc_stack->value.dc_type!=DC_NUMBER
+                       || dc_stack->link->value.dc_type!=DC_NUMBER
+                       || dc_stack->link->link->value.dc_type!=DC_NUMBER){
+               fprintf(stderr, "%s: non-numeric value\n", progname);
+               return;
+       }
+       (void)dc_pop(&c);
+       (void)dc_pop(&b);
+       (void)dc_pop(&a);
+       if ((*op)(a.v.number, b.v.number, c.v.number,
+                               kscale, &r.v.number) == DC_SUCCESS){
+               r.dc_type = DC_NUMBER;
+               dc_push(r);
+               dc_free_num(&a.v.number);
+               dc_free_num(&b.v.number);
+               dc_free_num(&c.v.number);
+       }else{
+               /* op failed; restore the stack */
+               dc_push(a);
+               dc_push(b);
+               dc_push(c);
+       }
+}
+
+\f
+/* initialize the register stacks to their initial values */
+void
+dc_register_init DC_DECLVOID()
+{
+       int i;
+
+       for (i=0; i<DC_REGCOUNT; ++i)
+               dc_register[i] = NULL;
+}
+
+/* clear the evaluation stack */
+void
+dc_clear_stack DC_DECLVOID()
+{
+       dc_list *n;
+       dc_list *t;
+
+       for (n=dc_stack; n!=NULL; n=t){
+               t = n->link;
+               if (n->value.dc_type == DC_NUMBER)
+                       dc_free_num(&n->value.v.number);
+               else if (n->value.dc_type == DC_STRING)
+                       dc_free_str(&n->value.v.string);
+               else
+                       dc_garbage("in stack", -1);
+               dc_array_free(n->array);
+               free(n);
+       }
+       dc_stack = NULL;
+}
+
+/* push a value onto the evaluation stack */
+void
+dc_push DC_DECLARG((value))
+       dc_data value DC_DECLEND
+{
+       dc_list *n = dc_alloc();
+
+       if (value.dc_type!=DC_NUMBER && value.dc_type!=DC_STRING)
+               dc_garbage("in data being pushed", -1);
+       n->value = value;
+       n->link = dc_stack;
+       dc_stack = n;
+}
+
+/* push a value onto the named register stack */
+void
+dc_register_push DC_DECLARG((stackid, value))
+       int stackid DC_DECLSEP
+       dc_data value DC_DECLEND
+{
+       dc_list *n = dc_alloc();
+
+       stackid = regmap(stackid);
+       n->value = value;
+       n->link = dc_register[stackid];
+       dc_register[stackid] = n;
+}
+
+/* set *result to the value on the top of the evaluation stack */
+/* The caller is responsible for duplicating the value if it
+ * is to be maintained as anything more than a transient identity.
+ *
+ * DC_FAIL is returned if the stack is empty (and *result unchanged),
+ * DC_SUCCESS is returned otherwise
+ */
+int
+dc_top_of_stack DC_DECLARG((result))
+       dc_data *result DC_DECLEND
+{
+       if (dc_stack == NULL){
+               Empty_Stack;
+               return DC_FAIL;
+       }
+       if (dc_stack->value.dc_type!=DC_NUMBER
+                       && dc_stack->value.dc_type!=DC_STRING)
+               dc_garbage("at top of stack", -1);
+       *result = dc_stack->value;
+       return DC_SUCCESS;
+}
+
+/* set *result to a dup of the value on the top of the named register stack */
+/*
+ * DC_FAIL is returned if the named stack is empty (and *result unchanged),
+ * DC_SUCCESS is returned otherwise
+ */
+int
+dc_register_get DC_DECLARG((regid, result))
+       int regid DC_DECLSEP
+       dc_data *result DC_DECLEND
+{
+       dc_list *r;
+
+       regid = regmap(regid);
+       r = dc_register[regid];
+       if (r==NULL || r->value.dc_type==DC_UNINITIALIZED){
+               fprintf(stderr, "%s: register ", progname);
+               dc_show_id(stderr, regid, " is empty\n");
+               return DC_FAIL;
+       }
+       *result = dc_dup(r->value);
+       return DC_SUCCESS;
+}
+
+/* set the top of the named register stack to the indicated value */
+/* If the named stack is empty, craft a stack entry to enter the
+ * value into.
+ */
+void
+dc_register_set DC_DECLARG((regid, value))
+       int regid DC_DECLSEP
+       dc_data value DC_DECLEND
+{
+       dc_list *r;
+
+       regid = regmap(regid);
+       r = dc_register[regid];
+       if (r == NULL)
+               dc_register[regid] = dc_alloc();
+       else if (r->value.dc_type == DC_NUMBER)
+               dc_free_num(&r->value.v.number);
+       else if (r->value.dc_type == DC_STRING)
+               dc_free_str(&r->value.v.string);
+       else if (r->value.dc_type == DC_UNINITIALIZED)
+               ;
+       else
+               dc_garbage("", regid);
+       dc_register[regid]->value = value;
+}
+
+/* pop from the evaluation stack
+ *
+ * DC_FAIL is returned if the stack is empty (and *result unchanged),
+ * DC_SUCCESS is returned otherwise
+ */
+int
+dc_pop DC_DECLARG((result))
+       dc_data *result DC_DECLEND
+{
+       dc_list *r;
+
+       r = dc_stack;
+       if (r==NULL || r->value.dc_type==DC_UNINITIALIZED){
+               Empty_Stack;
+               return DC_FAIL;
+       }
+       if (r->value.dc_type!=DC_NUMBER && r->value.dc_type!=DC_STRING)
+               dc_garbage("at top of stack", -1);
+       *result = r->value;
+       dc_stack = r->link;
+       dc_array_free(r->array);
+       free(r);
+       return DC_SUCCESS;
+}
+
+/* pop from the named register stack
+ *
+ * DC_FAIL is returned if the named stack is empty (and *result unchanged),
+ * DC_SUCCESS is returned otherwise
+ */
+int
+dc_register_pop DC_DECLARG((stackid, result))
+       int stackid DC_DECLSEP
+       dc_data *result DC_DECLEND
+{
+       dc_list *r;
+
+       stackid = regmap(stackid);
+       r = dc_register[stackid];
+       if (r == NULL){
+               fprintf(stderr, "%s: stack register ", progname);
+               dc_show_id(stderr, stackid, " is empty\n");
+               return DC_FAIL;
+       }
+       if (r->value.dc_type!=DC_NUMBER && r->value.dc_type!=DC_STRING)
+               dc_garbage(" stack", stackid);
+       *result = r->value;
+       dc_register[stackid] = r->link;
+       dc_array_free(r->array);
+       free(r);
+       return DC_SUCCESS;
+}
+
+\f
+/* tell how many entries are currently on the evaluation stack */
+int
+dc_tell_stackdepth DC_DECLVOID()
+{
+       dc_list *n;
+       int depth=0;
+
+       for (n=dc_stack; n!=NULL; n=n->link)
+               ++depth;
+       return depth;
+}
+
+
+/* return the length of the indicated data value;
+ * if discard_p is DC_TOSS, the deallocate the value when done
+ *
+ * The definition of a datum's length is deligated to the
+ * appropriate module.
+ */
+int
+dc_tell_length DC_DECLARG((value, discard_p))
+       dc_data value DC_DECLSEP
+       dc_discard discard_p DC_DECLEND
+{
+       int length;
+
+       if (value.dc_type == DC_NUMBER){
+               length = dc_numlen(value.v.number);
+               if (discard_p == DC_TOSS)
+                       dc_free_num(&value.v.number);
+       } else if (value.dc_type == DC_STRING) {
+               length = (int) dc_strlen(value.v.string);
+               if (discard_p == DC_TOSS)
+                       dc_free_str(&value.v.string);
+       } else {
+               dc_garbage("in tell_length", -1);
+               /*NOTREACHED*/
+               length = 0;     /*just to suppress spurious compiler warnings*/
+       }
+       return length;
+}
+
+\f
+
+/* print out all of the values on the evaluation stack */
+void
+dc_printall DC_DECLARG((obase))
+       int obase DC_DECLEND
+{
+       dc_list *n;
+
+       for (n=dc_stack; n!=NULL; n=n->link)
+               dc_print(n->value, obase, DC_WITHNL, DC_KEEP);
+}
+
+\f
+
+
+/* get the current array head for the named array */
+struct dc_array *
+dc_get_stacked_array DC_DECLARG((array_id))
+       int array_id DC_DECLEND
+{
+       dc_list *r = dc_register[regmap(array_id)];
+       return r == NULL ? NULL : r->array;
+}
+
+/* set the current array head for the named array */
+void
+dc_set_stacked_array DC_DECLARG((array_id, new_head))
+       int array_id DC_DECLSEP
+       struct dc_array *new_head DC_DECLEND
+{
+       dc_list *r;
+
+       array_id = regmap(array_id);
+       r = dc_register[array_id];
+       if (r == NULL)
+               r = dc_register[array_id] = dc_alloc();
+       r->array = new_head;
+}
+
+\f
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 4
+ * End:
+ * vi: set ts=4 :
+ */
diff --git a/dc/string.c b/dc/string.c
new file mode 100644 (file)
index 0000000..ff1e7f1
--- /dev/null
@@ -0,0 +1,220 @@
+/* 
+ * implement string functions for dc
+ *
+ * Copyright (C) 1994, 1997, 1998, 2006 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, you can either send email to this
+ * program's author (see below) or write to:
+ *
+ *    The Free Software Foundation, Inc.
+ *    51 Franklin Street, Fifth Floor
+ *    Boston, MA 02110-1301  USA
+ */
+
+/* This should be the only module that knows the internals of type dc_string */
+
+#include "config.h"
+
+#include <stdio.h>
+#ifdef HAVE_STDDEF_H
+# include <stddef.h>   /* ptrdiff_t */
+#else
+# define ptrdiff_t     size_t
+#endif
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>   /* memcpy */
+#else
+# ifdef HAVE_MEMORY_H
+#  include <memory.h>  /* memcpy, maybe */
+# else
+#  ifdef HAVE_STRINGS_H
+#   include <strings.h>        /* memcpy, maybe */
+#  endif
+# endif
+#endif
+#include "dc.h"
+#include "dc-proto.h"
+
+/* here is the completion of the dc_string type: */
+struct dc_string {
+       char *s_ptr;  /* pointer to base of string */
+       size_t s_len; /* length of counted string */
+       int  s_refs;  /* reference count to cut down on memory use by duplicates */
+};
+
+\f
+/* return a duplicate of the string in the passed value */
+/* The mismatched data types forces the caller to deal with
+ * bad dc_type'd dc_data values, and makes it more convenient
+ * for the caller to not have to do the grunge work of setting
+ * up a dc_type result.
+ */
+dc_data
+dc_dup_str DC_DECLARG((value))
+       dc_str value DC_DECLEND
+{
+       dc_data result;
+
+       ++value->s_refs;
+       result.v.string = value;
+       result.dc_type = DC_STRING;
+       return result;
+}
+
+/* free an instance of a dc_str value */
+void
+dc_free_str DC_DECLARG((value))
+       dc_str *value DC_DECLEND
+{
+       struct dc_string *string = *value;
+
+       if (--string->s_refs < 1){
+               free(string->s_ptr);
+               free(string);
+       }
+}
+
+/* Output a dc_str value.
+ * Add a trailing newline if "newline" is set.
+ * Free the value after use if discard_flag is set.
+ */
+void
+dc_out_str DC_DECLARG((value, newline, discard_flag))
+       dc_str value DC_DECLSEP
+       dc_newline newline DC_DECLSEP
+       dc_discard discard_flag DC_DECLEND
+{
+       fwrite(value->s_ptr, value->s_len, sizeof *value->s_ptr, stdout);
+       if (newline == DC_WITHNL)
+               putchar('\n');
+       if (discard_flag == DC_TOSS)
+               dc_free_str(&value);
+}
+
+/* make a copy of a string (base s, length len)
+ * into a dc_str value; return a dc_data result
+ * with this value
+ */
+dc_data
+dc_makestring DC_DECLARG((s, len))
+       const char *s DC_DECLSEP
+       size_t len DC_DECLEND
+{
+       dc_data result;
+       struct dc_string *string;
+
+       string = dc_malloc(sizeof *string);
+       string->s_ptr = dc_malloc(len+1);
+       memcpy(string->s_ptr, s, len);
+       string->s_ptr[len] = '\0';      /* nul terminated for those who need it */
+       string->s_len = len;
+       string->s_refs = 1;
+       result.v.string = string;
+       result.dc_type = DC_STRING;
+       return result;
+}
+
+/* read a dc_str value from FILE *fp;
+ * if ldelim == rdelim, then read until a ldelim char or EOF is reached;
+ * if ldelim != rdelim, then read until a matching rdelim for the
+ * (already eaten) first ldelim is read.
+ * Return a dc_data result with the dc_str value as its contents.
+ */
+dc_data
+dc_readstring DC_DECLARG((fp, ldelim, rdelim))
+       FILE *fp DC_DECLSEP
+       int ldelim DC_DECLSEP
+       int rdelim DC_DECLEND
+{
+       static char *line_buf = NULL;   /* a buffer to build the string in */ 
+       static size_t buflen = 0;               /* the current size of line_buf */
+       int depth=1;
+       int c;
+       char *p;
+       const char *end;
+
+       if (line_buf == NULL){
+               /* initial buflen should be large enough to handle most cases */
+               buflen = (size_t) 2016;
+               line_buf = dc_malloc(buflen);
+       }
+       p = line_buf;
+       end = line_buf + buflen;
+       for (;;){
+               c = getc(fp);
+               if (c == EOF)
+                       break;
+               else if (c == rdelim && --depth < 1)
+                       break;
+               else if (c == ldelim)
+                       ++depth;
+               if (p >= end){
+                       ptrdiff_t offset = p - line_buf;
+                       /* buflen increment should be big enough
+                        * to avoid execessive reallocs:
+                        */
+                       buflen += 2048;
+                       line_buf = realloc(line_buf, buflen);
+                       if (line_buf == NULL)
+                               dc_memfail();
+                       p = line_buf + offset;
+                       end = line_buf + buflen;
+               }
+               *p++ = c;
+       }
+       return dc_makestring(line_buf, (size_t)(p-line_buf));
+}
+
+/* return the base pointer of the dc_str value;
+ * This function is needed because no one else knows what dc_str
+ * looks like.
+ */
+const char *
+dc_str2charp DC_DECLARG((value))
+       dc_str value DC_DECLEND
+{
+       return value->s_ptr;
+}
+
+/* return the length of the dc_str value;
+ * This function is needed because no one else knows what dc_str
+ * looks like, and strlen(dc_str2charp(value)) won't work
+ * if there's an embedded '\0'.
+ */
+size_t
+dc_strlen DC_DECLARG((value))
+       dc_str value DC_DECLEND
+{
+       return value->s_len;
+}
+
+\f
+/* initialize the strings subsystem */
+void
+dc_string_init DC_DECLVOID()
+{
+       /* nothing to do for this implementation */
+}
+
+\f
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 4
+ * End:
+ * vi: set ts=4 :
+ */
diff --git a/depcomp b/depcomp
new file mode 100755 (executable)
index 0000000..04701da
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,530 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2005-07-09.11
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+  stat=$?
+
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mecanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[   ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+       set fnord "$@"
+       shift
+       shift
+       ;;
+    *)
+       set fnord "$@" "$arg"
+       shift
+       shift
+       ;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::   \1 \\:p' >> "$depfile"
+  echo "       " >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644 (file)
index 0000000..1bdc478
--- /dev/null
@@ -0,0 +1,11 @@
+## Process this file with automake to produce Makefile.in
+
+info_TEXINFOS = bc.texi dc.texi
+MAKEINFO = makeinfo --no-split
+
+MAINTAINERCLEANFILES = Makefile.in
+
+dist_man_MANS = bc.1 dc.1
+
+bc.dvi bc.pdf bc.html $(srcdir)/bc.info \
+dc.dvi dc.pdf dc.html $(srcdir)/dc.info :  texi-ver.incl
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644 (file)
index 0000000..a0858b8
--- /dev/null
@@ -0,0 +1,501 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = doc
+DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in $(srcdir)/texi-ver.incl.in texinfo.tex
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = texi-ver.incl
+SOURCES =
+DIST_SOURCES =
+INFO_DEPS = $(srcdir)/bc.info $(srcdir)/dc.info
+am__TEXINFO_TEX_DIR = $(srcdir)
+DVIS = bc.dvi dc.dvi
+PDFS = bc.pdf dc.pdf
+PSS = bc.ps dc.ps
+HTMLS = bc.html dc.html
+TEXINFOS = bc.texi dc.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(dist_man_MANS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BC_VERSION = @BC_VERSION@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DC_VERSION = @DC_VERSION@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = makeinfo --no-split
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+READLINELIB = @READLINELIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+info_TEXINFOS = bc.texi dc.texi
+MAINTAINERCLEANFILES = Makefile.in
+dist_man_MANS = bc.1 dc.1
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .html .info .pdf .ps .texi
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  doc/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  doc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+texi-ver.incl: $(top_builddir)/config.status $(srcdir)/texi-ver.incl.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+.texi.info:
+       restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+       am__cwd=`pwd` && cd $(srcdir) && \
+       rm -rf $$backupdir && mkdir $$backupdir && \
+       if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+         for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+           if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+         done; \
+       else :; fi && \
+       cd "$$am__cwd"; \
+       if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+        -o $@ $<; \
+       then \
+         rc=0; \
+         cd $(srcdir); \
+       else \
+         rc=$$?; \
+         cd $(srcdir) && \
+         $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+       fi; \
+       rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+       TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+       MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+       $(TEXI2DVI) $<
+
+.texi.pdf:
+       TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+       MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+       $(TEXI2PDF) $<
+
+.texi.html:
+       rm -rf $(@:.html=.htp)
+       if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+        -o $(@:.html=.htp) $<; \
+       then \
+         rm -rf $@; \
+         if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+           mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+       else \
+         if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+           rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+         exit 1; \
+       fi
+$(srcdir)/bc.info: bc.texi 
+bc.dvi: bc.texi 
+bc.pdf: bc.texi 
+bc.html: bc.texi 
+$(srcdir)/dc.info: dc.texi 
+dc.dvi: dc.texi 
+dc.pdf: dc.texi 
+dc.html: dc.texi 
+.dvi.ps:
+       TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+       $(DVIPS) -o $@ $<
+
+uninstall-info-am:
+       @$(PRE_UNINSTALL)
+       @if (install-info --version && \
+            install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+         list='$(INFO_DEPS)'; \
+         for file in $$list; do \
+           relfile=`echo "$$file" | sed 's|^.*/||'`; \
+           echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+           install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+         done; \
+       else :; fi
+       @$(NORMAL_UNINSTALL)
+       @list='$(INFO_DEPS)'; \
+       for file in $$list; do \
+         relfile=`echo "$$file" | sed 's|^.*/||'`; \
+         relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+         (if cd "$(DESTDIR)$(infodir)"; then \
+            echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+            rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+          else :; fi); \
+       done
+
+dist-info: $(INFO_DEPS)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       list='$(INFO_DEPS)'; \
+       for base in $$list; do \
+         case $$base in \
+           $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+         esac; \
+         if test -f $$base; then d=.; else d=$(srcdir); fi; \
+         for file in $$d/$$base*; do \
+           relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+           test -f $(distdir)/$$relfile || \
+             cp -p $$file $(distdir)/$$relfile; \
+         done; \
+       done
+
+mostlyclean-aminfo:
+       -rm -rf bc.aux bc.cp bc.cps bc.fn bc.fns bc.ky bc.kys bc.log bc.pg bc.pgs \
+         bc.tmp bc.toc bc.tp bc.tps bc.vr bc.vrs bc.dvi bc.pdf bc.ps \
+         bc.html dc.aux dc.cp dc.fn dc.fns dc.ky dc.log dc.pg dc.tmp \
+         dc.toc dc.tp dc.vr dc.dvi dc.pdf dc.ps dc.html
+
+maintainer-clean-aminfo:
+       @list='$(INFO_DEPS)'; for i in $$list; do \
+         i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+         echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+         rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+       done
+install-man1: $(man1_MANS) $(man_MANS)
+       @$(NORMAL_INSTALL)
+       test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)"
+       @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.1*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+         else file=$$i; fi; \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           1*) ;; \
+           *) ext='1' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+         $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
+       done
+uninstall-man1:
+       @$(NORMAL_UNINSTALL)
+       @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.1*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           1*) ;; \
+           *) ext='1' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
+         rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
+       done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+       $(MAKE) $(AM_MAKEFLAGS) \
+         top_distdir="$(top_distdir)" distdir="$(distdir)" \
+         dist-info
+check-am: all-am
+check: check-am
+all-am: Makefile $(INFO_DEPS) $(MANS)
+installdirs:
+       for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \
+         test -z "$$dir" || $(mkdir_p) "$$dir"; \
+       done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am install-man
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+       @$(NORMAL_INSTALL)
+       test -z "$(infodir)" || $(mkdir_p) "$(DESTDIR)$(infodir)"
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       list='$(INFO_DEPS)'; \
+       for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+         esac; \
+         if test -f $$file; then d=.; else d=$(srcdir); fi; \
+         file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+         for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+                       $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+           if test -f $$ifile; then \
+             relfile=`echo "$$ifile" | sed 's|^.*/||'`; \
+             echo " $(INSTALL_DATA) '$$ifile' '$(DESTDIR)$(infodir)/$$relfile'"; \
+             $(INSTALL_DATA) "$$ifile" "$(DESTDIR)$(infodir)/$$relfile"; \
+           else : ; fi; \
+         done; \
+       done
+       @$(POST_INSTALL)
+       @if (install-info --version && \
+            install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+         list='$(INFO_DEPS)'; \
+         for file in $$list; do \
+           relfile=`echo "$$file" | sed 's|^.*/||'`; \
+           echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+           install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+         done; \
+       else : ; fi
+install-man: install-man1
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+       maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-info-am uninstall-man
+
+uninstall-man: uninstall-man1
+
+.PHONY: all all-am check check-am clean clean-generic dist-info \
+       distclean distclean-generic distdir dvi dvi-am html html-am \
+       info info-am install install-am install-data install-data-am \
+       install-exec install-exec-am install-info install-info-am \
+       install-man install-man1 install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-aminfo maintainer-clean-generic mostlyclean \
+       mostlyclean-aminfo mostlyclean-generic pdf pdf-am ps ps-am \
+       uninstall uninstall-am uninstall-info-am uninstall-man \
+       uninstall-man1
+
+
+bc.dvi bc.pdf bc.html $(srcdir)/bc.info \
+dc.dvi dc.pdf dc.html $(srcdir)/dc.info :  texi-ver.incl
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/doc/bc.1 b/doc/bc.1
new file mode 100644 (file)
index 0000000..1b306f2
--- /dev/null
+++ b/doc/bc.1
@@ -0,0 +1,822 @@
+.\"
+.\" bc.1 - the *roff document processor source for the bc manual
+.\"
+.\" This file is part of GNU bc.
+.\" Copyright (C) 1991-1994, 1997, 2000, 2003, 2006 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 of the License , or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; see the file COPYING.  If not, write to:
+.\"   The Free Software Foundation, Inc.
+.\"   51 Franklin Street, Fifth Floor
+.\"   Boston, MA 02110-1301  USA
+.\"
+.\" You may contact the author by:
+.\" e-mail: philnelson@acm.org
+.\" us-mail: Philip A. Nelson
+.\" Computer Science Department, 9062
+.\" Western Washington University
+.\" Bellingham, WA 98226-9062
+.\"
+.\"
+.TH bc 1 "2006-06-11" "GNU Project"
+.SH NAME
+bc - An arbitrary precision calculator language
+.SH SYNTAX
+\fBbc\fR [ \fB-hlwsqv\fR ] [long-options] [ \fI file ...\fR ]
+.SH DESCRIPTION
+\fBbc\fR is a language that supports arbitrary precision numbers
+with interactive execution of statements.  There are some similarities
+in the syntax to the C programming language. 
+A standard math library is available by command line option.
+If requested, the math library is defined before processing any files.
+\fBbc\fR starts by processing code from all the files listed
+on the command line in the order listed.  After all files have been
+processed, \fBbc\fR reads from the standard input.  All code is
+executed as it is read.  (If a file contains a command to halt the
+processor, \fBbc\fR will never read from the standard input.)
+.PP
+This version of \fBbc\fR contains several extensions beyond
+traditional \fBbc\fR implementations and the POSIX draft standard.
+Command line options can cause these extensions to print a warning 
+or to be rejected.  This 
+document describes the language accepted by this processor.
+Extensions will be identified as such.
+.SS OPTIONS
+.IP "-h, --help"
+Print the usage and exit.
+.IP "-i, --interactive"
+Force interactive mode.
+.IP "-l, --mathlib"
+Define the standard math library.
+.IP "-w, --warn"
+Give warnings for extensions to POSIX \fBbc\fR.
+.IP "-s, --standard"
+Process exactly the POSIX \fBbc\fR language.
+.IP "-q, --quiet"
+Do not print the normal GNU bc welcome.
+.IP "-v, --version"
+Print the version number and copyright and quit.
+.SS NUMBERS
+The most basic element in \fBbc\fR is the number.  Numbers are
+arbitrary precision numbers.  This precision is both in the integer
+part and the fractional part.  All numbers are represented internally
+in decimal and all computation is done in decimal.  (This version
+truncates results from divide and multiply operations.)  There are two
+attributes of numbers, the length and the scale.  The length is the
+total number of significant decimal digits in a number and the scale
+is the total number of decimal digits after the decimal point.  For
+example:
+.nf
+.RS
+ .000001 has a length of 6 and scale of 6.
+ 1935.000 has a length of 7 and a scale of 3.
+.RE
+.fi
+.SS VARIABLES
+Numbers are stored in two types of variables, simple variables and
+arrays.  Both simple variables and array variables are named.  Names
+begin with a letter followed by any number of letters, digits and
+underscores.  All letters must be lower case.  (Full alpha-numeric
+names are an extension. In POSIX \fBbc\fR all names are a single
+lower case letter.)  The type of variable is clear by the context
+because all array variable names will be followed by brackets ([]).
+.PP
+There are four special variables, \fBscale, ibase, obase,\fR and
+\fBlast\fR.  \fBscale\fR defines how some operations use digits after the
+decimal point.  The default value of \fBscale\fR is 0. \fBibase\fR
+and \fBobase\fR define the conversion base for input and output
+numbers.  The default for both input and output is base 10.
+\fBlast\fR (an extension) is a variable that has the value of the last
+printed number.  These will be discussed in further detail where
+appropriate.  All of these variables may have values assigned to them
+as well as used in expressions.
+.SS COMMENTS
+Comments in \fBbc\fR start with the characters \fB/*\fR and end with
+the characters \fB*/\fR.  Comments may start anywhere and appear as a
+single space in the input.  (This causes comments to delimit other
+input items.  For example, a comment can not be found in the middle of
+a variable name.)  Comments include any newlines (end of line) between
+the start and the end of the comment.
+.PP
+To support the use of scripts for \fBbc\fR, a single line comment has been
+added as an extension.  A single line comment starts at a \fB#\fR
+character and continues to the next end of the line.  The end of line
+character is not part of the comment and is processed normally.
+.SS EXPRESSIONS
+The numbers are manipulated by expressions and statements.  Since
+the language was designed to be interactive, statements and expressions
+are executed as soon as possible.  There is no "main" program.  Instead,
+code is executed as it is encountered.  (Functions, discussed in
+detail later, are defined when encountered.)
+.PP
+A simple expression is just a constant. \fBbc\fR converts constants
+into internal decimal numbers using the current input base, specified
+by the variable \fBibase\fR. (There is an exception in functions.)
+The legal values of \fBibase\fR are 2 through 16.  Assigning a
+value outside this range to \fBibase\fR will result in a value of 2
+or 16.  Input numbers may contain the characters 0-9 and A-F. (Note:
+They must be capitals.  Lower case letters are variable names.)
+Single digit numbers always have the value of the digit regardless of
+the value of \fBibase\fR. (i.e. A = 10.)  For multi-digit numbers,
+\fBbc\fR changes all input digits greater or equal to ibase to the
+value of \fBibase\fR-1.  This makes the number \fBFFF\fR always be
+the largest 3 digit number of the input base.
+.PP
+Full expressions are similar to many other high level languages.
+Since there is only one kind of number, there are no rules for mixing
+types.  Instead, there are rules on the scale of expressions.  Every
+expression has a scale.  This is derived from the scale of original
+numbers, the operation performed and in many cases, the value of the
+variable \fBscale\fR. Legal values of the variable \fBscale\fR are
+0 to the maximum number representable by a C integer.
+.PP
+In the following descriptions of legal expressions, "expr" refers to a
+complete expression and "var" refers to a simple or an array variable.
+A simple variable is just a
+.RS
+\fIname\fR
+.RE
+and an array variable is specified as
+.RS
+\fIname\fR[\fIexpr\fR]
+.RE
+Unless specifically
+mentioned the scale of the result is the maximum scale of the
+expressions involved.
+.IP "- expr"
+The result is the negation of the expression.
+.IP "++ var"
+The variable is incremented by one and the new value is the result of
+the expression.
+.IP "-- var"
+The variable
+is decremented by one and the new value is the result of the
+expression.
+.IP "var ++"
+ The result of the expression is the value of
+the variable and then the variable is incremented by one.
+.IP "var --"
+The result of the expression is the value of the variable and then
+the variable is decremented by one.
+.IP "expr + expr"
+The result of the expression is the sum of the two expressions.
+.IP "expr - expr"
+The result of the expression is the difference of the two expressions.
+.IP "expr * expr"
+The result of the expression is the product of the two expressions.
+.IP "expr / expr"
+The result of the expression is the quotient of the two expressions.
+The scale of the result is the value of the variable \fBscale\fR.
+.IP "expr % expr"
+The result of the expression is the "remainder" and it is computed in the
+following way.  To compute a%b, first a/b is computed to \fBscale\fR
+digits.  That result is used to compute a-(a/b)*b to the scale of the
+maximum of \fBscale\fR+scale(b) and scale(a).  If \fBscale\fR is set
+to zero and both expressions are integers this expression is the
+integer remainder function.
+.IP "expr ^ expr"
+The result of the expression is the value of the first raised to the
+second. The second expression must be an integer.  (If the second
+expression is not an integer, a warning is generated and the
+expression is truncated to get an integer value.)  The scale of the
+result is \fBscale\fR if the exponent is negative.  If the exponent
+is positive the scale of the result is the minimum of the scale of the
+first expression times the value of the exponent and the maximum of
+\fBscale\fR and the scale of the first expression.  (e.g. scale(a^b)
+= min(scale(a)*b, max( \fBscale,\fR scale(a))).)  It should be noted
+that expr^0 will always return the value of 1.
+.IP "( expr )"
+This alters the standard precedence to force the evaluation of the
+expression.
+.IP "var = expr"
+The variable is assigned the value of the expression.
+.IP "var <op>= expr"
+This is equivalent to "var = var <op> expr" with the exception that
+the "var" part is evaluated only once.  This can make a difference if
+"var" is an array.
+.PP
+Relational expressions are a special kind of expression
+that always evaluate to 0 or 1, 0 if the relation is false and 1 if
+the relation is true.  These may appear in any legal expression.
+(POSIX bc requires that relational expressions are used only in if,
+while, and for statements and that only one relational test may be
+done in them.)  The relational operators are
+.IP "expr1 < expr2"
+The result is 1 if expr1 is strictly less than expr2.
+.IP "expr1 <= expr2"
+The result is 1 if expr1 is less than or equal to expr2.
+.IP "expr1 > expr2"
+The result is 1 if expr1 is strictly greater than expr2.
+.IP "expr1 >= expr2"
+The result is 1 if expr1 is greater than or equal to expr2.
+.IP "expr1 == expr2"
+The result is 1 if expr1 is equal to expr2.
+.IP "expr1 != expr2"
+The result is 1 if expr1 is not equal to expr2.
+.PP
+Boolean operations are also legal.  (POSIX \fBbc\fR does NOT have
+boolean operations). The result of all boolean operations are 0 and 1
+(for false and true) as in relational expressions.  The boolean
+operators are:
+.IP "!expr"
+The result is 1 if expr is 0.
+.IP "expr && expr"
+The result is 1 if both expressions are non-zero.
+.IP "expr || expr"
+The result is 1 if either expression is non-zero.
+.PP
+The expression precedence is as follows: (lowest to highest)
+.nf
+.RS
+|| operator, left associative
+&& operator, left associative
+! operator, nonassociative
+Relational operators, left associative
+Assignment operator, right associative
++ and - operators, left associative
+*, / and % operators, left associative
+^ operator, right associative
+unary - operator, nonassociative
+++ and -- operators, nonassociative
+.RE
+.fi
+.PP
+This precedence was chosen so that POSIX compliant \fBbc\fR programs
+will run correctly. This will cause the use of the relational and
+logical operators to have some unusual behavior when used with
+assignment expressions.  Consider the expression:
+.RS
+a = 3 < 5
+.RE
+.PP
+Most C programmers would assume this would assign the result of "3 <
+5" (the value 1) to the variable "a".  What this does in \fBbc\fR is
+assign the value 3 to the variable "a" and then compare 3 to 5.  It is
+best to use parenthesis when using relational and logical operators
+with the assignment operators.
+.PP
+There are a few more special expressions that are provided in \fBbc\fR.
+These have to do with user defined functions and standard
+functions.  They all appear as "\fIname\fB(\fIparameters\fB)\fR".
+See the section on functions for user defined functions.  The standard
+functions are:
+.IP "length ( expression )"
+The value of the length function is the number of significant digits in the
+expression.
+.IP "read ( )"
+The read function (an extension) will read a number from the standard
+input, regardless of where the function occurs.   Beware, this can
+cause problems with the mixing of data and program in the standard input.
+The best use for this function is in a previously written program that
+needs input from the user, but never allows program code to be input
+from the user.  The value of the read function is the number read from
+the standard input using the current value of the variable 
+\fBibase\fR for the conversion base.
+.IP "scale ( expression )"
+The value of the scale function is the number of digits after the decimal
+point in the expression.
+.IP "sqrt ( expression )"
+The value of the sqrt function is the square root of the expression.  If
+the expression is negative, a run time error is generated.
+.SS STATEMENTS
+Statements (as in most algebraic languages) provide the sequencing of
+expression evaluation.  In \fBbc\fR statements are executed "as soon
+as possible."  Execution happens when a newline in encountered and
+there is one or more complete statements.  Due to this immediate
+execution, newlines are very important in \fBbc\fR. In fact, both a
+semicolon and a newline are used as statement separators.  An
+improperly placed newline will cause a syntax error.  Because newlines
+are statement separators, it is possible to hide a newline by using
+the backslash character.  The sequence "\e<nl>", where <nl> is the
+newline appears to \fBbc\fR as whitespace instead of a newline.  A
+statement list is a series of statements separated by semicolons and
+newlines.  The following is a list of \fBbc\fR statements and what
+they do: (Things enclosed in brackets ([]) are optional parts of the
+statement.)
+.IP "expression"
+This statement does one of two things.  If the expression starts with
+"<variable> <assignment> ...", it is considered to be an assignment
+statement.  If the expression is not an assignment statement, the
+expression is evaluated and printed to the output.  After the number
+is printed, a newline is printed.  For example, "a=1" is an assignment
+statement and "(a=1)" is an expression that has an embedded
+assignment.  All numbers that are printed are printed in the base
+specified by the variable \fBobase\fR. The legal values for \fB
+obase\fR are 2 through BC_BASE_MAX.  (See the section LIMITS.)  For
+bases 2 through 16, the usual method of writing numbers is used.  For
+bases greater than 16, \fBbc\fR uses a multi-character digit method
+of printing the numbers where each higher base digit is printed as a
+base 10 number.  The multi-character digits are separated by spaces.
+Each digit contains the number of characters required to represent the
+base ten value of "obase-1".  Since numbers are of arbitrary
+precision, some numbers may not be printable on a single output line.
+These long numbers will be split across lines using the "\e" as the
+last character on a line.  The maximum number of characters printed
+per line is 70.  Due to the interactive nature of \fBbc\fR, printing
+a number causes the side effect of assigning the printed value to the
+special variable \fBlast\fR. This allows the user to recover the
+last value printed without having to retype the expression that
+printed the number.  Assigning to \fBlast\fR is legal and will
+overwrite the last printed value with the assigned value.  The newly
+assigned value will remain until the next number is printed or another
+value is assigned to \fBlast\fR.  (Some installations may allow the 
+use of a single period (.) which is not part of a number as a short
+hand notation for for \fBlast\fR.)
+.IP "string"
+The string is printed to the output.  Strings start with a double quote
+character and contain all characters until the next double quote character.
+All characters are take literally, including any newline.  No newline
+character is printed after the string.
+.IP "\fBprint\fR list"
+The print statement (an extension) provides another method of output.
+The "list" is a list of strings and expressions separated by commas.
+Each string or expression is printed in the order of the list.  No
+terminating newline is printed.  Expressions are evaluated and their
+value is printed and assigned to the variable \fBlast\fR. Strings
+in the print statement are printed to the output and may contain
+special characters.  Special characters start with the backslash
+character (\e).  The special characters recognized by \fBbc\fR are
+"a" (alert or bell), "b" (backspace), "f" (form feed), "n" (newline),
+"r" (carriage return), "q" (double quote), "t" (tab), and "\e" (backslash).
+Any other character following the backslash will be ignored.  
+.IP "{ statement_list }"
+This is the compound statement.  It allows multiple statements to be
+grouped together for execution.
+.IP "\fBif\fR ( expression ) statement1 [\fBelse\fR statement2]"
+The if statement evaluates the expression and executes statement1 or
+statement2 depending on the value of the expression.  If the expression
+is non-zero, statement1 is executed.  If statement2 is present and
+the value of the expression is 0, then statement2 is executed.  (The
+else clause is an extension.)
+.IP "\fBwhile\fR ( expression ) statement"
+The while statement will execute the statement while the expression
+is non-zero.  It evaluates the expression before each execution of
+the statement.   Termination of the loop is caused by a zero
+expression value or the execution of a break statement.
+.IP "\fBfor\fR ( [expression1] ; [expression2] ; [expression3] ) statement"
+The for statement controls repeated execution of the statement.  
+Expression1 is evaluated before the loop.  Expression2 is evaluated
+before each execution of the statement.  If it is non-zero, the statement
+is evaluated.  If it is zero, the loop is terminated.  After each
+execution of the statement, expression3 is evaluated before the reevaluation
+of expression2.  If expression1 or expression3 are missing, nothing is
+evaluated at the point they would be evaluated.
+If expression2 is missing, it is the same as substituting
+the value 1 for expression2.  (The optional expressions are an
+extension. POSIX \fBbc\fR requires all three expressions.)
+The following is equivalent code for the for statement:
+.nf
+.RS
+expression1;
+while (expression2) {
+   statement;
+   expression3;
+}
+.RE
+.fi
+.IP "\fBbreak\fR"
+This statement causes a forced exit of the most recent enclosing while
+statement or for statement.
+.IP "\fBcontinue\fR"
+The continue statement (an extension)  causes the most recent enclosing
+for statement to start the next iteration.
+.IP "\fBhalt\fR"
+The halt statement (an extension) is an executed statement that causes
+the \fBbc\fR processor to quit only when it is executed.  For example,
+"if (0 == 1) halt" will not cause \fBbc\fR to terminate because the halt is
+not executed.
+.IP "\fBreturn\fR"
+Return the value 0 from a function.  (See the section on functions.)
+.IP "\fBreturn\fR ( expression )"
+Return the value of the expression from a function.  (See the section on 
+functions.)  As an extension, the parenthesis are not required.
+.SS PSEUDO STATEMENTS
+These statements are not statements in the traditional sense.  They are
+not executed statements.  Their function is performed at "compile" time.
+.IP "\fBlimits\fR"
+Print the local limits enforced by the local version of \fBbc\fR.  This
+is an extension.
+.IP "\fBquit\fR"
+When the quit statement is read, the \fBbc\fR processor
+is terminated, regardless of where the quit statement is found.  For
+example, "if (0 == 1) quit" will cause \fBbc\fR to terminate.
+.IP "\fBwarranty\fR"
+Print a longer warranty notice.  This is an extension.
+.SS FUNCTIONS
+Functions provide a method of defining a computation that can be executed
+later.  Functions in 
+.B bc
+always compute a value and return it to the caller.  Function definitions
+are "dynamic" in the sense that a function is undefined until a definition
+is encountered in the input.  That definition is then used until another
+definition function for the same name is encountered.  The new definition
+then replaces the older definition.  A function is defined as follows:
+.nf
+.RS
+\fBdefine \fIname \fB( \fIparameters \fB) { \fInewline
+\fI    auto_list   statement_list \fB}\fR
+.RE
+.fi
+A function call is just an expression of the form
+"\fIname\fB(\fIparameters\fB)\fR".
+.PP
+Parameters are numbers or arrays (an extension).  In the function definition,
+zero or more parameters are defined by listing their names separated by
+commas.  All parameters are call by value parameters.  
+Arrays are specified in the parameter definition by
+the notation "\fIname\fB[]\fR".   In the function call, actual parameters
+are full expressions for number parameters.  The same notation is used
+for passing arrays as for defining array parameters.  The named array is
+passed by value to the function.  Since function definitions are dynamic,
+parameter numbers and types are checked when a function is called.  Any
+mismatch in number or types of parameters will cause a runtime error.
+A runtime error will also occur for the call to an undefined function.
+.PP
+The \fIauto_list\fR is an optional list of variables that are for
+"local" use.  The syntax of the auto list (if present) is "\fBauto
+\fIname\fR, ... ;".  (The semicolon is optional.)  Each \fIname\fR is
+the name of an auto variable.  Arrays may be specified by using the
+same notation as used in parameters.  These variables have their
+values pushed onto a stack at the start of the function.  The
+variables are then initialized to zero and used throughout the
+execution of the function.  At function exit, these variables are
+popped so that the original value (at the time of the function call)
+of these variables are restored.  The parameters are really auto
+variables that are initialized to a value provided in the function
+call.  Auto variables are different than traditional local variables
+because if function A calls function B, B may access function
+A's auto variables by just using the same name, unless function B has
+called them auto variables.  Due to the fact that auto variables and
+parameters are pushed onto a stack, \fBbc\fR supports recursive functions.
+.PP
+The function body is a list of \fBbc\fR statements.  Again, statements
+are separated by semicolons or newlines.  Return statements cause the
+termination of a function and the return of a value.  There are two
+versions of the return statement.  The first form, "\fBreturn\fR", returns
+the value 0 to the calling expression.  The second form, 
+"\fBreturn ( \fIexpression \fB)\fR", computes the value of the expression
+and returns that value to the calling expression.  There is an implied
+"\fBreturn (0)\fR" at the end of every function.  This allows a function
+to terminate and return 0 without an explicit return statement.
+.PP
+Functions also change the usage of the variable \fBibase\fR.  All
+constants in the function body will be converted using the value of
+\fBibase\fR at the time of the function call.  Changes of \fBibase\fR
+will be ignored during the execution of the function except for the
+standard function \fBread\fR, which will always use the current value
+of \fBibase\fR for conversion of numbers.
+.PP
+Several extensions have been added to functions.  First, the format of
+the definition has been slightly relaxed.  The standard requires the
+opening brace be on the same line as the \fBdefine\fR keyword and all
+other parts must be on following lines.  This version of \fBbc\fR will
+allow any number of newlines before and after the opening brace of the
+function.  For example, the following definitions are legal.
+.nf
+.RS
+\f(CW
+define d (n) { return (2*n); }
+define d (n)
+  { return (2*n); }
+\fR
+.RE
+.fi
+.PP
+Functions may be defined as \fBvoid\fR.  A void
+funtion returns no value and thus may not be used in any place that needs
+a value.  A void function does not produce any output when called by itself
+on an input line.  The key word \fBvoid\fR is placed between the key word
+\fBdefine\fR and the function name.  For example, consider the following
+session.
+.nf
+.RS
+\f(CW
+define py (y) { print "--->", y, "<---", "\n"; }
+define void px (x) { print "--->", x, "<---", "\n"; }
+py(1)
+--->1<---
+0
+px(1)
+--->1<---
+\fR
+.RE
+.fi
+Since \fBpy\fR is not a void function, the call of \fBpy(1)\fR prints
+the desired output and then prints a second line that is the value of
+the function.  Since the value of a function that is not given an
+explicit return statement is zero, the zero is printed.  For \fBpx(1)\fR,
+no zero is printed because the function is a void function.
+.PP
+Also, call by variable for arrays was added.  To declare
+a call by variable array, the declaration of the array parameter in the
+function definition looks like "\fI*name\fB[]\fR".  The call to the
+function remains the same as call by value arrays. 
+.SS MATH LIBRARY
+If \fBbc\fR is invoked with the \fB-l\fR option, a math library is preloaded
+and the default scale is set to 20.   The math functions will calculate their
+results to the scale set at the time of their call.  
+The math library defines the following functions:
+.IP "s (\fIx\fR)"
+The sine of x, x is in radians.
+.IP "c (\fIx\fR)"
+The cosine of x, x is in radians.
+.IP "a (\fIx\fR)"
+The arctangent of x, arctangent returns radians.
+.IP "l (\fIx\fR)"
+The natural logarithm of x.
+.IP "e (\fIx\fR)"
+The exponential function of raising e to the value x.
+.IP "j (\fIn,x\fR)"
+The Bessel function of integer order n of x.
+.SS EXAMPLES
+In /bin/sh,  the following will assign the value of "pi" to the shell
+variable \fBpi\fR.
+.RS
+\f(CW
+pi=$(echo "scale=10; 4*a(1)" | bc -l)
+\fR
+.RE
+.PP
+The following is the definition of the exponential function used in the
+math library.  This function is written in POSIX \fBbc\fR.
+.nf
+.RS
+\f(CW
+scale = 20
+
+/* Uses the fact that e^x = (e^(x/2))^2
+   When x is small enough, we use the series:
+     e^x = 1 + x + x^2/2! + x^3/3! + ...
+*/
+
+define e(x) {
+  auto  a, d, e, f, i, m, v, z
+
+  /* Check the sign of x. */
+  if (x<0) {
+    m = 1
+    x = -x
+  } 
+
+  /* Precondition x. */
+  z = scale;
+  scale = 4 + z + .44*x;
+  while (x > 1) {
+    f += 1;
+    x /= 2;
+  }
+
+  /* Initialize the variables. */
+  v = 1+x
+  a = x
+  d = 1
+
+  for (i=2; 1; i++) {
+    e = (a *= x) / (d *= i)
+    if (e == 0) {
+      if (f>0) while (f--)  v = v*v;
+      scale = z
+      if (m) return (1/v);
+      return (v/1);
+    }
+    v += e
+  }
+}
+\fR
+.RE
+.fi
+.PP
+The following is code that uses the extended features of \fBbc\fR to
+implement a simple program for calculating checkbook balances.  This
+program is best kept in a file so that it can be used many times 
+without having to retype it at every use.
+.nf
+.RS
+\f(CW
+scale=2
+print "\enCheck book program!\en"
+print "  Remember, deposits are negative transactions.\en"
+print "  Exit by a 0 transaction.\en\en"
+
+print "Initial balance? "; bal = read()
+bal /= 1
+print "\en"
+while (1) {
+  "current balance = "; bal
+  "transaction? "; trans = read()
+  if (trans == 0) break;
+  bal -= trans
+  bal /= 1
+}
+quit
+\fR
+.RE
+.fi
+.PP
+The following is the definition of the recursive factorial function.
+.nf
+.RS
+\f(CW
+define f (x) {
+  if (x <= 1) return (1);
+  return (f(x-1) * x);
+}
+\fR
+.RE
+.fi
+.SS READLINE AND LIBEDIT OPTIONS
+GNU \fBbc\fR can be compiled (via a configure option) to use the GNU
+\fBreadline\fR input editor library or the BSD \fBlibedit\fR library.
+This allows the user to do editing of lines before sending them
+to \fBbc\fR.  It also allows for a history of previous lines typed.
+When this option is selected, \fBbc\fR has one more special variable.
+This special variable, \fBhistory\fR is the number of lines of history
+retained.  For \fBreadline\fR, a value of -1 means that an unlimited
+number of history lines are retained.  Setting the value of
+\fBhistory\fR to a positive number restricts the number of history
+lines to the number given.  The value of 0 disables the history
+feature.  The default value is 100. For more information, read the
+user manuals for the GNU \fBreadline\fR, \fBhistory\fR and BSD \fBlibedit\fR
+libraries.  One can not enable both \fBreadline\fR and \fBlibedit\fR
+at the same time.
+.SS DIFFERENCES
+This version of 
+.B bc
+was implemented from the POSIX P1003.2/D11 draft and contains
+several differences and extensions relative to the draft and
+traditional implementations.
+It is not implemented in the traditional way using
+.I dc(1).
+This version is a single process which parses and runs a byte code
+translation of the program.  There is an "undocumented" option (-c)
+that causes the program to output the byte code to
+the standard output instead of running it.  It was mainly used for
+debugging the parser and preparing the math library.
+.PP
+A major source of differences is
+extensions, where a feature is extended to add more functionality and
+additions, where new features are added. 
+The following is the list of differences and extensions.
+.IP "LANG environment"
+This version does not conform to the POSIX standard in the processing
+of the LANG environment variable and all environment variables starting
+with LC_.
+.IP "names"
+Traditional and POSIX
+.B bc
+have single letter names for functions, variables and arrays.  They have
+been extended to be multi-character names that start with a letter and
+may contain letters, numbers and the underscore character.
+.IP "Strings"
+Strings are not allowed to contain NUL characters.  POSIX says all characters
+must be included in strings.
+.IP "last"
+POSIX \fBbc\fR does not have a \fBlast\fR variable.  Some implementations
+of \fBbc\fR use the period (.) in a similar way.  
+.IP "comparisons"
+POSIX \fBbc\fR allows comparisons only in the if statement, the while
+statement, and the second expression of the for statement.  Also, only
+one relational operation is allowed in each of those statements.
+.IP "if statement, else clause"
+POSIX \fBbc\fR does not have an else clause.
+.IP "for statement"
+POSIX \fBbc\fR requires all expressions to be present in the for statement.
+.IP "&&, ||, !"
+POSIX \fBbc\fR does not have the logical operators.
+.IP "read function"
+POSIX \fBbc\fR does not have a read function.
+.IP "print statement"
+POSIX \fBbc\fR does not have a print statement .
+.IP "continue statement"
+POSIX \fBbc\fR does not have a continue statement.
+.IP "return statement"
+POSIX \fBbc\fR requires parentheses around the return expression.
+.IP "array parameters"
+POSIX \fBbc\fR does not (currently) support array parameters in full.
+The POSIX grammar allows for arrays in function definitions, but does
+not provide a method to specify an array as an actual parameter.  (This
+is most likely an oversight in the grammar.)  Traditional implementations
+of \fBbc\fR have only call by value array parameters.
+.IP "function format"
+POSIX \fBbc\fR requires the opening brace on the same line as the 
+\fBdefine\fR key word and the \fBauto\fR statement on the next line.
+.IP "=+, =-, =*, =/, =%, =^"
+POSIX \fBbc\fR does not require these "old style" assignment operators to
+be defined.  This version may allow these "old style" assignments.  Use
+the limits statement to see if the installed version supports them.  If
+it does support the "old style" assignment operators, the statement
+"a =- 1" will decrement \fBa\fR by 1 instead of setting \fBa\fR to the
+value -1.
+.IP "spaces in numbers"
+Other implementations of \fBbc\fR allow spaces in numbers.  For example,
+"x=1 3" would assign the value 13 to the variable x.  The same statement
+would cause a syntax error in this version of \fBbc\fR.
+.IP "errors and execution"
+This implementation varies from other implementations in terms of what
+code will be executed when syntax and other errors are found in the
+program.  If a syntax error is found in a function definition, error
+recovery tries to find the beginning of a statement and continue to
+parse the function.  Once a syntax error is found in the function, the
+function will not be callable and becomes undefined.
+Syntax errors in the interactive execution code will invalidate the
+current execution block.  The execution block is terminated by an
+end of line that appears after a complete sequence of statements.
+For example, 
+.nf
+.RS
+a = 1
+b = 2
+.RE
+.fi
+has two execution blocks and
+.nf
+.RS
+{ a = 1
+  b = 2 }
+.RE
+.fi
+has one execution block.  Any runtime error will terminate the execution
+of the current execution block.  A runtime warning will not terminate the
+current execution block.
+.IP "Interrupts"
+During an interactive session, the SIGINT signal (usually generated by
+the control-C character from the terminal) will cause execution of the
+current execution block to be interrupted.  It will display a "runtime"
+error indicating which function was interrupted.  After all runtime
+structures have been cleaned up, a message will be printed to notify the
+user that \fBbc\fR is ready for more input.  All previously defined functions
+remain defined and the value of all non-auto variables are the value at
+the point of interruption.  All auto variables and function parameters
+are removed during the
+clean up process.  During a non-interactive
+session, the SIGINT signal will terminate the entire run of \fBbc\fR.
+.SS LIMITS
+The following are the limits currently in place for this 
+.B bc
+processor.  Some of them may have been changed by an installation.
+Use the limits statement to see the actual values.
+.IP "BC_BASE_MAX"
+The maximum output base is currently set at 999.  The maximum input base
+is 16.
+.IP "BC_DIM_MAX"
+This is currently an arbitrary limit of 65535 as distributed.  Your
+installation may be different.
+.IP "BC_SCALE_MAX"
+The number of digits after the decimal point is limited to INT_MAX digits.
+Also, the number of digits before the decimal point is limited to INT_MAX
+digits.
+.IP "BC_STRING_MAX"
+The limit on the number of characters in a string is INT_MAX characters.
+.IP "exponent"
+The value of the exponent in the raise operation (^) is limited to LONG_MAX.
+.IP "variable names"
+The current limit on the number of unique names is 32767 for each of
+simple variables, arrays and functions.
+.SH ENVIRONMENT VARIABLES
+The following environment variables are processed by \fBbc\fR:
+.IP "POSIXLY_CORRECT"
+This is the same as the \fB-s\fR option.
+.IP "BC_ENV_ARGS"
+This is another mechanism to get arguments to \fBbc\fR.  The
+format is the same as the command line arguments.  These arguments
+are processed first, so any files listed in the environment arguments
+are processed before any command line argument files.  This allows
+the user to set up "standard" options and files to be processed
+at every invocation of \fBbc\fR.  The files in the environment
+variables would typically contain function definitions for functions
+the user wants defined every time \fBbc\fR is run.
+.IP "BC_LINE_LENGTH"
+This should be an integer specifying the number of characters in an
+output line for numbers. This includes the backslash and newline characters
+for long numbers.  As an extension, the value of zero disables the 
+multi-line feature.  Any other value of this variable that is less than
+3 sets the line length to 70.
+.SH DIAGNOSTICS
+If any file on the command line can not be opened, \fBbc\fR will report
+that the file is unavailable and terminate.  Also, there are compile
+and run time diagnostics that should be self-explanatory.
+.SH BUGS
+Error recovery is not very good yet.
+.PP
+Email bug reports to
+.BR bug-bc@gnu.org .
+Be sure to include the word ``bc'' somewhere in the ``Subject:'' field.
+.SH AUTHOR
+.nf
+Philip A. Nelson
+philnelson@acm.org
+.fi
+.SH ACKNOWLEDGEMENTS
+The author would like to thank Steve Sommars (Steve.Sommars@att.com) for
+his extensive help in testing the implementation.  Many great suggestions
+were given.  This is a much better product due to his involvement.
diff --git a/doc/bc.info b/doc/bc.info
new file mode 100644 (file)
index 0000000..b18a931
--- /dev/null
@@ -0,0 +1,1030 @@
+This is bc.info, produced by makeinfo version 4.8 from bc.texi.
+
+START-INFO-DIR-ENTRY
+* bc: (bc).                    An arbitrary precision calculator language.
+END-INFO-DIR-ENTRY
+
+\1f
+File: bc.info,  Node: Top,  Next: Introduction,  Prev: (dir),  Up: (dir)
+
+* Menu:
+
+* Introduction::
+* Basic Elements::
+* Expressions::
+* Statements::
+* Functions::
+* Examples::
+* Readline and Libedit Options::
+* Comparison with Other Implementations::
+* Limits::
+* Environment Variables::
+
+\1f
+File: bc.info,  Node: Introduction,  Next: Basic Elements,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+* Menu:
+
+* Description::
+* Command Line Options::
+
+\1f
+File: bc.info,  Node: Description,  Next: Command Line Options,  Prev: Introduction,  Up: Introduction
+
+1.1 Description
+===============
+
+`bc' [ -hlwsqv ] [long-options] [  FILE ... ]
+
+   `bc' is a language that supports arbitrary precision numbers with
+interactive execution of statements.  There are some similarities in
+the syntax to the C programming language.  A standard math library is
+available by command line option.  If requested, the math library is
+defined before processing any files.  `bc' starts by processing code
+from all the files listed on the command line in the order listed.
+After all files have been processed, `bc' reads from the standard
+input.  All code is executed as it is read.  (If a file contains a
+command to halt the processor, `bc' will never read from the standard
+input.)
+
+   This version of `bc' contains several extensions beyond traditional
+`bc' implementations and the POSIX draft standard.  Command line
+options can cause these extensions to print a warning or to be
+rejected.  This document describes the language accepted by this
+processor.  Extensions will be identified as such.
+
+   The author would like to thank Steve Sommars
+(<Steve.Sommars@att.com>) for his extensive help in testing the
+implementation.  Many great suggestions were given.  This is a much
+better product due to his involvement.
+
+   Email bug reports to <bug-bc@gnu.org>.  Be sure to include the word
+"bc" somewhere in the "Subject:" field.
+
+\1f
+File: bc.info,  Node: Command Line Options,  Next: Numbers,  Prev: Description,  Up: Introduction
+
+1.2 Command Line Options
+========================
+
+`bc' takes the following options from the command line:
+`-h, --help'
+     Print the usage and exit.
+
+`-l, --mathlib'
+     Define the standard math library.
+
+`-w, --warn'
+     Give warnings for extensions to POSIX `bc'.
+
+`-s, --standard'
+     Process exactly the POSIX `bc' language.
+
+`-q, --quiet'
+     Do not print the normal GNU `bc' welcome.
+
+`-v, --version'
+     Print the version number and copyright and quit.
+
+
+\1f
+File: bc.info,  Node: Basic Elements,  Next: Expressions,  Prev: Introduction,  Up: Top
+
+2 Basic Elements
+****************
+
+* Menu:
+
+* Numbers::
+* Variables::
+* Comments::
+
+\1f
+File: bc.info,  Node: Numbers,  Next: Variables,  Prev: Command Line Options,  Up: Basic Elements
+
+2.1 Numbers
+===========
+
+The most basic element in `bc' is the number.  Numbers are arbitrary
+precision numbers.  This precision is both in the integer part and the
+fractional part.  All numbers are represented internally in decimal and
+all computation is done in decimal.  (This version truncates results
+from divide and multiply operations.)  There are two attributes of
+numbers, the length and the scale.  The length is the total number of
+significant decimal digits in a number and the scale is the total number
+of decimal digits after the decimal point.  For example, .000001 has a
+length of 6 and scale of 6, while 1935.000 has a length of 7 and a scale
+of 3.
+
+\1f
+File: bc.info,  Node: Variables,  Next: Comments,  Prev: Numbers,  Up: Basic Elements
+
+2.2 Variables
+=============
+
+Numbers are stored in two types of variables, simple variables and
+arrays.  Both simple variables and array variables are named.  Names
+begin with a letter followed by any number of letters, digits and
+underscores.  All letters must be lower case.  (Full alphanumeric names
+are an extension. In POSIX `bc' all names are a single lower case
+letter.)  The type of variable is clear by the context because all
+array variable names will be followed by brackets ( [ ] ).
+
+   There are four special variables, SCALE, IBASE, OBASE, and LAST.
+SCALE defines how some operations use digits after the decimal point.
+The default value of SCALE is 0. IBASE and OBASE define the conversion
+base for input and output numbers.  The default for both input and
+output is base 10.  LAST (an extension) is a variable that has the
+value of the last printed number.  These will be discussed in further
+detail where appropriate.  All of these variables may have values
+assigned to them as well as used in expressions.
+
+\1f
+File: bc.info,  Node: Comments,  Prev: Variables,  Up: Basic Elements
+
+2.3 Comments
+============
+
+Comments in `bc' start with the characters `/*' and end with the
+characters `*/'.  Comments may start anywhere and appear as a single
+space in the input.  (This causes comments to delimit other input
+items.  For example, a comment can not be found in the middle of a
+variable name.)  Comments include any newlines (end of line) between
+the start and the end of the comment.
+
+   To support the use of scripts for `bc', a single line comment has
+been added as an extension.  A single line comment starts at a `#'
+character and continues to the next end of the line.  The end of line
+character is not part of the comment and is processed normally.
+
+\1f
+File: bc.info,  Node: Expressions,  Next: Statements,  Prev: Basic Elements,  Up: Top
+
+3 Expressions
+*************
+
+* Menu:
+
+* About Expressions and Special Variables::
+* Basic Expressions::
+* Relational Expressions::
+* Boolean Expressions::
+* Precedence::
+* Special Expressions::
+
+\1f
+File: bc.info,  Node: About Expressions and Special Variables,  Next: Basic Expressions,  Prev: Expressions,  Up: Expressions
+
+3.1 About Expressions and Special Variables
+===========================================
+
+The numbers are manipulated by expressions and statements.  Since the
+language was designed to be interactive, statements and expressions are
+executed as soon as possible.  There is no main program.  Instead, code
+is executed as it is encountered.  (Functions, discussed in detail
+later, are defined when encountered.)
+
+   A simple expression is just a constant. `bc' converts constants into
+internal decimal numbers using the current input base, specified by the
+variable IBASE. (There is an exception in functions.)  The legal values
+of IBASE are 2 through 16.  Assigning a value outside this range to
+IBASE will result in a value of 2 or 16.  Input numbers may contain the
+characters 0-9 and A-F. (Note: They must be capitals.  Lower case
+letters are variable names.)  Single digit numbers always have the
+value of the digit regardless of the value of IBASE. (i.e. A = 10.)
+For multi-digit numbers, `bc' changes all input digits greater or equal
+to IBASE to the value of IBASE-1.  This makes the number `FFF' always
+be the largest 3 digit number of the input base.
+
+   Full expressions are similar to many other high level languages.
+Since there is only one kind of number, there are no rules for mixing
+types.  Instead, there are rules on the scale of expressions.  Every
+expression has a scale.  This is derived from the scale of original
+numbers, the operation performed and in many cases, the value of the
+variable SCALE. Legal values of the variable SCALE are 0 to the maximum
+number representable by a C integer.
+
+\1f
+File: bc.info,  Node: Basic Expressions,  Next: Relational Expressions,  Prev: About Expressions and Special Variables,  Up: Expressions
+
+3.2 Basic Expressions
+=====================
+
+In the following descriptions of legal expressions, "expr" refers to a
+complete expression and "VAR" refers to a simple or an array variable.
+A simple variable is just a
+
+   NAME
+
+   and an array variable is specified as
+
+   NAME[EXPR]
+
+   Unless specifically mentioned the scale of the result is the maximum
+scale of the expressions involved.
+
+`- expr'
+     The result is the negation of the expression.
+
+`++ VAR'
+     The variable is incremented by one and the new value is the result
+     of the expression.
+
+`-- VAR'
+     The variable is decremented by one and the new value is the result
+     of the expression.
+
+`VAR ++'
+     The result of the expression is the value of the variable and then
+     the variable is incremented by one.
+
+`VAR --'
+     The result of the expression is the value of the variable and then
+     the variable is decremented by one.
+
+`expr + expr'
+     The result of the expression is the sum of the two expressions.
+
+`expr - expr'
+     The result of the expression is the difference of the two
+     expressions.
+
+`expr * expr'
+     The result of the expression is the product of the two expressions.
+
+`expr / expr'
+     The result of the expression is the quotient of the two
+     expressions.  The scale of the result is the value of the variable
+     `scale'
+
+`expr % expr'
+     The result of the expression is the "remainder" and it is computed
+     in the following way.  To compute a%b, first a/b is computed to
+     SCALE digits.  That result is used to compute a-(a/b)*b to the
+     scale of the maximum of SCALE+scale(b) and scale(a).  If SCALE is
+     set to zero and both expressions are integers this expression is
+     the integer remainder function.
+
+`expr ^ expr'
+     The result of the expression is the value of the first raised to
+     the second. The second expression must be an integer.  (If the
+     second expression is not an integer, a warning is generated and the
+     expression is truncated to get an integer value.)  The scale of the
+     result is SCALE if the exponent is negative.  If the exponent is
+     positive the scale of the result is the minimum of the scale of the
+     first expression times the value of the exponent and the maximum of
+     SCALE and the scale of the first expression.  (e.g. scale(a^b) =
+     min(scale(a)*b, max(SCALE, scale(a))).)  It should be noted that
+     expr^0 will always return the value of 1.
+
+`( expr )'
+     This alters the standard precedence to force the evaluation of the
+     expression.
+
+`VAR = expr'
+     The variable is assigned the value of the expression.
+
+`VAR <op>= expr'
+     This is equivalent to "VAR = VAR <op> expr" with the exception
+     that the "VAR" part is evaluated only once.  This can make a
+     difference if "VAR" is an array.
+
+\1f
+File: bc.info,  Node: Relational Expressions,  Next: Boolean Expressions,  Prev: Basic Expressions,  Up: Expressions
+
+3.3 Relational Expressions
+==========================
+
+Relational expressions are a special kind of expression that always
+evaluate to 0 or 1, 0 if the relation is false and 1 if the relation is
+true.  These may appear in any legal expression.  (POSIX `bc' requires
+that relational expressions are used only in `if', `while', and `for'
+statements and that only one relational test may be done in them.)  The
+relational operators are
+
+`expr1 < expr2'
+     The result is 1 if expr1 is strictly less than expr2.
+
+`expr1 <= expr2'
+     The result is 1 if expr1 is less than or equal to expr2.
+
+`expr1 > expr2'
+     The result is 1 if expr1 is strictly greater than expr2.
+
+`expr1 >= expr2'
+     The result is 1 if expr1 is greater than or equal to expr2.
+
+`expr1 == expr2'
+     The result is 1 if expr1 is equal to expr2.
+
+`expr1 != expr2'
+     The result is 1 if expr1 is not equal to expr2.
+
+\1f
+File: bc.info,  Node: Boolean Expressions,  Next: Precedence,  Prev: Relational Expressions,  Up: Expressions
+
+3.4 Boolean Expressions
+=======================
+
+Boolean operations are also legal.  (POSIX `bc' does NOT have boolean
+operations). The result of all boolean operations are 0 and 1 (for
+false and true) as in relational expressions.  The boolean operators
+are:
+
+`!expr'
+     The result is 1 if expr is 0.
+
+`expr && expr'
+     The result is 1 if both expressions are non-zero.
+
+`expr || expr'
+     The result is 1 if either expression is non-zero.
+
+\1f
+File: bc.info,  Node: Precedence,  Next: Special Expressions,  Prev: Boolean Expressions,  Up: Expressions
+
+3.5 Precedence
+==============
+
+The expression precedence is as follows: (lowest to highest)
+
+     || operator, left associative
+     && operator, left associative
+     ! operator, nonassociative
+     Relational operators, left associative
+     Assignment operator, right associative
+     + and - operators, left associative
+     *, / and % operators, left associative
+     ^ operator, right associative
+     unary - operator, nonassociative
+     ++ and -- operators, nonassociative
+
+   This precedence was chosen so that POSIX compliant `bc' programs
+will run correctly. This will cause the use of the relational and
+logical operators to have some unusual behavior when used with
+assignment expressions.  Consider the expression:
+
+     a = 3 < 5
+
+   Most C programmers would assume this would assign the result of "3 <
+5" (the value 1) to the variable "a".  What this does in `bc' is assign
+the value 3 to the variable "a" and then compare 3 to 5.  It is best to
+use parentheses when using relational and logical operators with the
+assignment operators.
+
+\1f
+File: bc.info,  Node: Special Expressions,  Prev: Precedence,  Up: Expressions
+
+3.6 Special Expressions
+=======================
+
+There are a few more special expressions that are provided in `bc'.
+These have to do with user-defined functions and standard functions.
+They all appear as "NAME`('PARAMETERS`)'".  *Note Functions::, for
+user-defined functions.  The standard functions are:
+
+`length ( expression )'
+     The value of the length function is the number of significant
+     digits in the expression.
+
+`read ( )'
+     The `read' function (an extension) will read a number from the
+     standard input, regardless of where the function occurs.  Beware,
+     this can cause problems with the mixing of data and program in the
+     standard input.  The best use for this function is in a previously
+     written program that needs input from the user, but never allows
+     program code to be input from the user.  The value of the `read'
+     function is the number read from the standard input using the
+     current value of the variable IBASE for the conversion base.
+
+`scale ( expression )'
+     The value of the `scale' function is the number of digits after the
+     decimal point in the expression.
+
+`sqrt ( expression )'
+     The value of the `sqrt' function is the square root of the
+     expression.  If the expression is negative, a run time error is
+     generated.
+
+\1f
+File: bc.info,  Node: Statements,  Next: Functions,  Prev: Expressions,  Up: Top
+
+4 Statements
+************
+
+* Menu:
+
+* Pseudo Statements::
+
+   Statements (as in most algebraic languages) provide the sequencing of
+expression evaluation.  In `bc' statements are executed "as soon as
+possible."  Execution happens when a newline in encountered and there
+is one or more complete statements.  Due to this immediate execution,
+newlines are very important in `bc'. In fact, both a semicolon and a
+newline are used as statement separators.  An improperly placed newline
+will cause a syntax error.  Because newlines are statement separators,
+it is possible to hide a newline by using the backslash character.  The
+sequence "\<nl>", where <nl> is the newline appears to `bc' as
+whitespace instead of a newline.  A statement list is a series of
+statements separated by semicolons and newlines.  The following is a
+list of `bc' statements and what they do: (Things enclosed in brackets
+( [ ] ) are optional parts of the statement.)
+
+EXPRESSION
+     This statement does one of two things.  If the expression starts
+     with "<variable> <assignment> ...", it is considered to be an
+     assignment statement.  If the expression is not an assignment
+     statement, the expression is evaluated and printed to the output.
+     After the number is printed, a newline is printed.  For example,
+     "a=1" is an assignment statement and "(a=1)" is an expression that
+     has an embedded assignment.  All numbers that are printed are
+     printed in the base specified by the variable OBASE. The legal
+     values for OBASE are 2 through BC_BASE_MAX (*note Environment
+     Variables::).  For bases 2 through 16, the usual method of writing
+     numbers is used.  For bases greater than 16, `bc' uses a
+     multi-character digit method of printing the numbers where each
+     higher base digit is printed as a base 10 number.  The
+     multi-character digits are separated by spaces.  Each digit
+     contains the number of characters required to represent the base
+     ten value of "OBASE -1".  Since numbers are of arbitrary
+     precision, some numbers may not be printable on a single output
+     line.  These long numbers will be split across lines using the "\"
+     as the last character on a line.  The maximum number of characters
+     printed per line is 70.  Due to the interactive nature of `bc',
+     printing a number causes the side effect of assigning the printed
+     value to the special variable LAST. This allows the user to
+     recover the last value printed without having to retype the
+     expression that printed the number.  Assigning to LAST is legal
+     and will overwrite the last printed value with the assigned value.
+     The newly assigned value will remain until the next number is
+     printed or another value is assigned to LAST.  (Some installations
+     may allow the use of a single period (.) which is not part of a
+     number as a short hand notation for for LAST.)
+
+STRING
+     The string is printed to the output.  Strings start with a double
+     quote character and contain all characters until the next double
+     quote character.  All characters are taken literally, including
+     any newline.  No newline character is printed after the string.
+
+`PRINT' LIST
+     The `print' statement (an extension) provides another method of
+     output.  The LIST is a list of strings and expressions separated by
+     commas.  Each string or expression is printed in the order of the
+     list.  No terminating newline is printed.  Expressions are
+     evaluated and their value is printed and assigned to the variable
+     `last'. Strings in the print statement are printed to the output
+     and may contain special characters.  Special characters start with
+     the backslash character (\e).  The special characters recognized
+     by `bc' are "a" (alert or bell), "b" (backspace), "f" (form feed),
+     "n" (newline), "r" (carriage return), "q" (double quote), "t"
+     (tab), and "\e" (backslash).  Any other character following the
+     backslash will be ignored.
+
+{ STATEMENT_LIST }
+     This is the compound statement.  It allows multiple statements to
+     be grouped together for execution.
+
+`IF' ( EXPRESSION ) STATEMENT1 [`ELSE' STATEMENT2]
+     The if statement evaluates the expression and executes statement1
+     or statement2 depending on the value of the expression.  If the
+     expression is non-zero, statement1 is executed.  If statement2 is
+     present and the value of the expression is 0, then statement2 is
+     executed.  (The `else' clause is an extension.)
+
+`WHILE' ( EXPRESSION ) STATEMENT
+     The while statement will execute the statement while the expression
+     is non-zero.  It evaluates the expression before each execution of
+     the statement.   Termination of the loop is caused by a zero
+     expression value or the execution of a `break' statement.
+
+`FOR' ( [EXPRESSION1] ; [EXPRESSION2] ; [EXPRESSION3] ) STATEMENT
+     The `for' statement controls repeated execution of the statement.
+     EXPRESSION1 is evaluated before the loop.  EXPRESSION2 is
+     evaluated before each execution of the statement.  If it is
+     non-zero, the statement is evaluated.  If it is zero, the loop is
+     terminated.  After each execution of the statement, EXPRESSION3 is
+     evaluated before the reevaluation of expression2.  If EXPRESSION1
+     or EXPRESSION3 are missing, nothing is evaluated at the point they
+     would be evaluated.  If EXPRESSION2 is missing, it is the same as
+     substituting the value 1 for EXPRESSION2.  (The optional
+     expressions are an extension. POSIX `bc' requires all three
+     expressions.)  The following is equivalent code for the `for'
+     statement:
+
+          expression1;
+          while (expression2) {
+             statement;
+             expression3;
+          }
+
+`BREAK'
+     This statement causes a forced exit of the most recent enclosing
+     `while' statement or `for' statement.
+
+`CONTINUE'
+     The `continue' statement (an extension)  causes the most recent
+     enclosing `for' statement to start the next iteration.
+
+`HALT'
+     The `halt' statement (an extension) is an executed statement that
+     causes the `bc' processor to quit only when it is executed.  For
+     example, "if (0 == 1) halt" will not cause `bc' to terminate
+     because the `halt' is not executed.
+
+`RETURN'
+     Return the value 0 from a function.  (*Note Functions::.)
+
+`RETURN' ( EXPRESSION )
+     Return the value of the expression from a function.  (*Note
+     Functions::.)  As an extension, the parenthesis are not required.
+
+\1f
+File: bc.info,  Node: Pseudo Statements,  Prev: Statements,  Up: Statements
+
+4.1 Pseudo Statements
+=====================
+
+These statements are not statements in the traditional sense.  They are
+not executed statements.  Their function is performed at "compile" time.
+
+`limits'
+     Print the local limits enforced by the local version of `bc'.  This
+     is an extension.
+
+`quit'
+     When the `quit' statement is read, the `bc' processor is
+     terminated, regardless of where the `quit' statement is found.  For
+     example, "if (0 == 1) quit" will cause `bc' to terminate.
+
+`warranty'
+     Print a longer warranty notice.  This is an extension.
+
+\1f
+File: bc.info,  Node: Functions,  Next: Examples,  Prev: Statements,  Up: Top
+
+5 Functions
+***********
+
+* Menu:
+
+* Math Library Functions::
+
+   Functions provide a method of defining a computation that can be
+executed later.  Functions in `bc' always compute a value and return it
+to the caller.  Function definitions are "dynamic" in the sense that a
+function is undefined until a definition is encountered in the input.
+That definition is then used until another definition function for the
+same name is encountered.  The new definition then replaces the older
+definition.  A function is defined as follows:
+
+     `define' NAME `(' PARAMETERS `)' `{' NEWLINE
+         AUTO_LIST   STATEMENT_LIST `}'
+
+   A function call is just an expression of the form "`name'
+`('PARAMETERS`)'".
+
+   Parameters are numbers or arrays (an extension).  In the function
+definition, zero or more parameters are defined by listing their names
+separated by commas.  All parameters  are call by value parameters.
+Arrays are specified in the parameter definition by the notation
+"NAME`[ ]'".   In the function call, actual parameters are full
+expressions for number parameters.  The same notation is used for
+passing arrays as for defining array parameters.  The named array is
+passed by value to the function.  Since function definitions are
+dynamic, parameter numbers and types are checked when a function is
+called.  Any mismatch in number or types of parameters will cause a
+runtime error.  A runtime error will also occur for the call to an
+undefined function.
+
+   The AUTO_LIST is an optional list of variables that are for "local"
+use.  The syntax of the auto list (if present) is "`auto' NAME, ... ;".
+(The semicolon is optional.)  Each NAME is the name of an auto
+variable.  Arrays may be specified by using the same notation as used
+in parameters.  These variables have their values pushed onto a stack
+at the start of the function.  The variables are then initialized to
+zero and used throughout the execution of the function.  At function
+exit, these variables are popped so that the original value (at the
+time of the function call) of these variables are restored.  The
+parameters are really auto variables that are initialized to a value
+provided in the function call.  Auto variables are different than
+traditional local variables because if function A calls function B, B
+may access function A's auto variables by just using the same name,
+unless function B has called them auto variables.  Due to the fact that
+auto variables and parameters are pushed onto a stack, `bc' supports
+recursive functions.
+
+   The function body is a list of `bc' statements.  Again, statements
+are separated by semicolons or newlines.  Return statements cause the
+termination of a function and the return of a value.  There are two
+versions of the return statement.  The first form, "`return'", returns
+the value 0 to the calling expression.  The second form, "`return' (
+EXPRESSION )", computes the value of the expression and returns that
+value to the calling expression.  There is an implied "`return' (0)" at
+the end of every function.  This allows a function to terminate and
+return 0 without an explicit `return' statement.
+
+   Functions also change the usage of the variable IBASE.  All
+constants in the function body will be converted using the value of
+IBASE at the time of the function call.  Changes of IBASE will be
+ignored during the execution of the function except for the standard
+function `read', which will always use the current value of IBASE for
+conversion of numbers.
+
+   Several extensions have been added to functions.  First, the format
+of the definition has been slightly relaxed.  The standard requires the
+opening brace be on the same line as the `define' keyword and all other
+parts must be on following lines.  This version of `bc' will allow any
+number of newlines before and after the opening brace of the function.
+For example, the following definitions are legal.
+
+        define d (n) { return (2*n); }
+        define d (n)
+            { return (2*n); }
+
+   Functions may be defined as `void'.  A void funtion returns no value
+and thus may not be used in any place that needs a value.  A void
+function does not produce any output when called by itself on an input
+line.  The key word `void' is placed between the key word `define' and
+the function name.  For example, consider the following session.
+
+     define py (y) { print "--->", y, "<---", "\n"; }
+     define void px (x) { print "--->", x, "<---", "\n"; }
+     py(1)
+     --->1<---
+     0
+     px(1)
+     --->1<---
+
+   Since `py' is not a void function, the call of `py(1)' prints the
+desired output and then prints a second line that is the value of the
+function.  Since the value of a function that is not given an explicit
+return statement is zero, the zero is printed.  For `px(1)', no zero is
+printed because the function is a void function.
+
+   Also, call by variable for arrays was added.  To declare a call by
+variable array, the declaration of the array parameter in the function
+definition looks like "`*'NAME`[]'".  The call to the function remains
+the same as call by value arrays.
+
+\1f
+File: bc.info,  Node: Math Library Functions,  Prev: Functions,  Up: Functions
+
+5.1 Math Library Functions
+==========================
+
+If `bc' is invoked with the `-l' option, a math library is preloaded
+and the default SCALE is set to 20.  The math functions will calculate
+their results to the scale set at the time of their call.  The math
+library defines the following functions:
+
+`s (X)'
+     The sine of X, X is in radians.
+
+`c (X)'
+     The cosine of X, X is in radians.
+
+`a (X)'
+     The arctangent of X, arctangent returns radians.
+
+`l (X)'
+     The natural logarithm of X.
+
+`e (X)'
+     The exponential function of raising E to the value X.
+
+`j (N,X)'
+     The Bessel function of integer order N of X.
+
+\1f
+File: bc.info,  Node: Examples,  Next: Readline and Libedit Options,  Prev: Functions,  Up: Top
+
+6 Examples
+**********
+
+In /bin/sh,  the following will assign the value of "pi" to the shell
+variable PI.
+
+     pi=$(echo "scale=10; 4*a(1)" | bc -l)
+
+   The following is the definition of the exponential function used in
+the math library.  This function is written in POSIX `bc'.
+
+
+     scale = 20
+
+     /* Uses the fact that e^x = (e^(x/2))^2
+        When x is small enough, we use the series:
+          e^x = 1 + x + x^2/2! + x^3/3! + ...
+     */
+
+     define e(x) {
+       auto  a, d, e, f, i, m, v, z
+
+       /* Check the sign of x. */
+       if (x<0) {
+         m = 1
+         x = -x
+       }
+
+       /* Precondition x. */
+       z = scale;
+       scale = 4 + z + .44*x;
+       while (x > 1) {
+         f += 1;
+         x /= 2;
+       }
+
+       /* Initialize the variables. */
+       v = 1+x
+       a = x
+       d = 1
+
+       for (i=2; 1; i++) {
+         e = (a *= x) / (d *= i)
+         if (e == 0) {
+           if (f>0) while (f--)  v = v*v;
+           scale = z
+           if (m) return (1/v);
+           return (v/1);
+         }
+         v += e
+       }
+     }
+
+   The following is code that uses the extended features of `bc' to
+implement a simple program for calculating checkbook balances.  This
+program is best kept in a file so that it can be used many times
+without having to retype it at every use.
+
+
+     scale=2
+     print "\nCheck book program\n!"
+     print "  Remember, deposits are negative transactions.\n"
+     print "  Exit by a 0 transaction.\n\n"
+
+     print "Initial balance? "; bal = read()
+     bal /= 1
+     print "\n"
+     while (1) {
+       "current balance = "; bal
+       "transaction? "; trans = read()
+       if (trans == 0) break;
+       bal -= trans
+       bal /= 1
+     }
+     quit
+
+   The following is the definition of the recursive factorial function.
+
+
+     define f (x) {
+       if (x <= 1) return (1);
+       return (f(x-1) * x);
+     }
+
+\1f
+File: bc.info,  Node: Readline and Libedit Options,  Next: Comparison with Other Implementations,  Prev: Examples,  Up: Top
+
+7 Readline and Libedit Options
+******************************
+
+GNU `bc' can be compiled (via a configure option) to use the GNU
+`readline' input editor library or the BSD `libedit' library.  This
+allows the user to do more editing of lines before sending them to
+`bc'.  It also allows for a history of previous lines typed.  When this
+option is selected, `bc' has one more special variable.  This special
+variable, HISTORY is the number of lines of history retained.  A value
+of -1 means that an unlimited number of history lines are retained.
+This is the default value.  Setting the value of HISTORY to a positive
+number restricts the number of history lines to the number given.  The
+value of 0 disables the history feature.  For more information, read
+the user manuals for the GNU `readline', `history' and BSD `libedit'
+libraries.  One can not enable both `readline' and `libedit' at the
+same time.
+
+\1f
+File: bc.info,  Node: Comparison with Other Implementations,  Next: Limits,  Prev: Readline and Libedit Options,  Up: Top
+
+8 Comparison with Other Implementations
+***************************************
+
+This version of `bc' was implemented from the POSIX P1003.2/D11 draft
+and contains several differences and extensions relative to the draft
+and traditional implementations.  It is not implemented in the
+traditional way using `dc'.  This version is a single process which
+parses and runs a byte code translation of the program.  There is an
+"undocumented" option (-c) that causes the program to output the byte
+code to the standard output instead of running it.  It was mainly used
+for debugging the parser and preparing the math library.
+
+   A major source of differences is extensions, where a feature is
+extended to add more functionality and additions, where new features
+are added.  The following is the list of differences and extensions.
+
+LANG ENVIRONMENT
+     This version does not conform to the POSIX standard in the
+     processing of the LANG environment variable and all environment
+     variables starting with LC_.
+
+NAMES
+     Traditional and POSIX `bc' have single letter names for functions,
+     variables and arrays.  They have been extended to be
+     multi-character names that start with a letter and may contain
+     letters, numbers and the underscore character.
+
+STRINGS
+     Strings are not allowed to contain NUL characters.  POSIX says all
+     characters must be included in strings.
+
+LAST
+     POSIX `bc' does not have a \fBlast variable.  Some implementations
+     of `bc' use the period (.) in a similar way.
+
+COMPARISONS
+     POSIX `bc' allows comparisons only in the `if' statement, the
+     `while' statement, and the second expression of the `for'
+     statement.  Also, only one relational operation is allowed in each
+     of those statements.
+
+IF STATEMENT, ELSE CLAUSE
+     POSIX `bc' does not have an `else' clause.
+
+FOR STATEMENT
+     POSIX `bc' requires all expressions to be present in the `for'
+     statement.
+
+&&, ||, !
+     POSIX `bc' does not have the logical operators.
+
+READ FUNCTION
+     POSIX `bc' does not have a `read' function.
+
+PRINT STATEMENT
+     POSIX `bc' does not have a `print' statement.
+
+CONTINUE STATEMENT
+     POSIX `bc' does not have a continue statement.
+
+ARRAY PARAMETERS
+     POSIX `bc' does not (currently) support array parameters in full.
+     The POSIX grammar allows for arrays in function definitions, but
+     does not provide a method to specify an array as an actual
+     parameter.  (This is most likely an oversight in the grammar.)
+     Traditional implementations of `bc' have only call by value array
+     parameters.
+
+FUNCTION FORMAT
+     POSIX `bc' requires the opening brace on the same line as the
+     `define' key word and the `auto' statement on the next line.
+
+=+, =-, =*, =/, =%, =^
+     POSIX `bc' does not require these "old style" assignment operators
+     to be defined.  This version may allow these "old style"
+     assignments.  Use the `limits' statement to see if the installed
+     version supports them.  If it does support the "old style"
+     assignment operators, the statement "a =- 1" will decrement `a' by
+     1 instead of setting `a' to the value -1.
+
+SPACES IN NUMBERS
+     Other implementations of `bc' allow spaces in numbers.  For
+     example, "x=1 3" would assign the value 13 to the variable x.  The
+     same statement would cause a syntax error in this version of `bc'.
+
+ERRORS AND EXECUTION
+     This implementation varies from other implementations in terms of
+     what code will be executed when syntax and other errors are found
+     in the program.  If a syntax error is found in a function
+     definition, error recovery tries to find the beginning of a
+     statement and continue to parse the function.  Once a syntax error
+     is found in the function, the function will not be callable and
+     becomes undefined.  Syntax errors in the interactive execution
+     code will invalidate the current execution block.  The execution
+     block is terminated by an end of line that appears after a
+     complete sequence of statements.  For example,
+
+          a = 1
+          b = 2
+
+     has two execution blocks and
+
+          { a = 1
+            b = 2 }
+
+     has one execution block.  Any runtime error will terminate the
+     execution of the current execution block.  A runtime warning will
+     not terminate the current execution block.
+
+INTERRUPTS
+     During an interactive session, the SIGINT signal (usually
+     generated by the control-C character from the terminal) will cause
+     execution of the current execution block to be interrupted.  It
+     will display a "runtime" error indicating which function was
+     interrupted.  After all runtime structures have been cleaned up, a
+     message will be printed to notify the user that `bc' is ready for
+     more input.  All previously defined functions remain defined and
+     the value of all non-auto variables are the value at the point of
+     interruption.  All auto variables and function parameters are
+     removed during the clean up process.  During a non-interactive
+     session, the SIGINT signal will terminate the entire run of `bc'.
+
+\1f
+File: bc.info,  Node: Limits,  Next: Environment Variables,  Prev: Comparison with Other Implementations,  Up: Top
+
+9 Limits
+********
+
+The following are the limits currently in place for this `bc'
+processor.  Some of them may have been changed by an installation.  Use
+the `limits' statement to see the actual values.
+
+`BC_BASE_MAX'
+     The maximum output base is currently set at 999.  The maximum
+     input base is 16.
+
+`BC_DIM_MAX'
+     This is currently an arbitrary limit of 65535 as distributed.  Your
+     installation may be different.
+
+`BC_SCALE_MAX'
+     The number of digits after the decimal point is limited to INT_MAX
+     digits.  Also, the number of digits before the decimal point is
+     limited to INT_MAX digits.
+
+`BC_STRING_MAX'
+     The limit on the number of characters in a string is INT_MAX
+     characters.
+
+`exponent'
+     The value of the exponent in the raise operation (^) is limited to
+     LONG_MAX.
+
+`multiply'
+     The multiply routine may yield incorrect results if a number has
+     more than LONG_MAX / 90 total digits.  For 32 bit longs, this
+     number is 23,860,929 digits.
+
+`variable names'
+     The current limit on the number of unique names is 32767 for each
+     of simple variables, arrays and functions.
+
+\1f
+File: bc.info,  Node: Environment Variables,  Prev: Limits,  Up: Top
+
+10 Environment Variables
+************************
+
+The following environment variables are processed by `bc':
+
+`POSIXLY_CORRECT'
+     This is the same as the -s option (*note Command Line Options::).
+
+`BC_ENV_ARGS'
+     This is another mechanism to get arguments to `bc'.  The format is
+     the same as the command line arguments.  These arguments are
+     processed first, so any files listed in the environment arguments
+     are processed before any command line argument files.  This allows
+     the user to set up "standard" options and files to be processed at
+     every invocation of `bc'.  The files in the environment variables
+     would typically contain function definitions for functions the user
+     wants defined every time `bc' is run.
+
+`BC_LINE_LENGTH'
+     This should be an integer specifying the number of characters in an
+     output line for numbers. This includes the backslash and newline
+     characters for long numbers. As an extension, the value of zero
+     disables the multi-line feature.  Any other value of this variable
+     that is less than 3 sets the line length to 70.
+
+
+\1f
+Tag Table:
+Node: Top\7f181
+Node: Introduction\7f473
+Node: Description\7f638
+Node: Command Line Options\7f2097
+Node: Basic Elements\7f2667
+Node: Numbers\7f2842
+Node: Variables\7f3610
+Node: Comments\7f4724
+Node: Expressions\7f5470
+Node: About Expressions and Special Variables\7f5754
+Node: Basic Expressions\7f7495
+Node: Relational Expressions\7f10441
+Node: Boolean Expressions\7f11451
+Node: Precedence\7f12011
+Node: Special Expressions\7f13176
+Node: Statements\7f14563
+Node: Pseudo Statements\7f21192
+Node: Functions\7f21845
+Node: Math Library Functions\7f27008
+Node: Examples\7f27723
+Node: Readline and Libedit Options\7f29707
+Node: Comparison with Other Implementations\7f30738
+Node: Limits\7f35990
+Node: Environment Variables\7f37247
+\1f
+End Tag Table
diff --git a/doc/bc.texi b/doc/bc.texi
new file mode 100644 (file)
index 0000000..d6162b6
--- /dev/null
@@ -0,0 +1,1049 @@
+\input texinfo  @c -*-texinfo-*-
+@c %**start of header
+@setfilename bc.info
+@settitle bc Command Manual
+@c %**end of header
+
+@include texi-ver.incl
+
+@c This file has the new style title page commands.
+@c Run `makeinfo' rather than `texinfo-format-buffer'.
+
+@smallbook
+
+@c tex
+@c \overfullrule=0pt
+@c end tex
+
+@ifinfo
+@direntry
+* bc: (bc).                    An arbitrary precision calculator language.
+@end direntry
+@end ifinfo
+
+@titlepage
+@title @command{bc}
+@subtitle an arbitrary precision calculator language
+@subtitle version @value{BC_VERSION}
+
+@author Philip A. Nelson
+@page
+
+This manual documents @command{bc}, an arbitrary precision calculator language.
+
+This manual is part of GNU @command{bc}.@*
+@sp 4
+Copyright (C) 1991, 1992, 1993, 1994, 1997, 2003, 2006 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor,  Boston, MA 02110-1301  USA.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+
+You may contact the author by:
+e-mail: @email{phil@@cs.wwu.edu}@*
+us-mail: Philip A. Nelson@*
+Computer Science Department, 9062@*
+Western Washington University@*
+Bellingham, WA 98226-9062
+
+@end titlepage
+
+@node Top, Introduction, (dir), (dir)
+
+@menu
+* Introduction::
+* Basic Elements::
+* Expressions::
+* Statements::
+* Functions::
+* Examples::
+* Readline and Libedit Options::
+* Comparison with Other Implementations::
+* Limits::
+* Environment Variables::
+@end menu
+
+@node Introduction, Basic Elements, Top, Top
+@chapter Introduction
+@menu
+* Description::
+* Command Line Options::
+@end menu
+
+@node Description, Command Line Options, Introduction, Introduction
+@section Description
+
+@command{bc} [ -hlwsqv ] [long-options] [ @var{ file ...} ]
+
+@command{bc} is a language that supports arbitrary precision numbers
+with interactive execution of statements.  There are some similarities
+in the syntax to the C programming language. 
+A standard math library is available by command line option.
+If requested, the math library is defined before processing any files.
+@command{bc} starts by processing code from all the files listed
+on the command line in the order listed.  After all files have been
+processed, @command{bc} reads from the standard input.  All code is
+executed as it is read.  (If a file contains a command to halt the
+processor, @command{bc} will never read from the standard input.)
+
+This version of @command{bc} contains several extensions beyond
+traditional @command{bc} implementations and the POSIX draft standard.
+Command line options can cause these extensions to print a warning or to
+be rejected.  This document describes the language accepted by this
+processor.  Extensions will be identified as such.
+
+The author would like to thank Steve Sommars
+(@email{Steve.Sommars@@att.com}) for his extensive help in testing the
+implementation.  Many great suggestions were given.  This is a much
+better product due to his involvement.
+
+Email bug reports to @email{bug-bc@@gnu.org}.  Be sure to include
+the word ``bc'' somewhere in the ``Subject:'' field.
+
+@node Command Line Options, Numbers, Description, Introduction
+@section Command Line Options
+
+@command{bc} takes the following options from the command line:
+@table @code
+
+@item -h, --help
+Print the usage and exit.
+
+@item -l, --mathlib
+Define the standard math library.
+
+@item -w, --warn
+Give warnings for extensions to POSIX @command{bc}.
+
+@item -s, --standard
+Process exactly the POSIX @command{bc} language.
+
+@item -q, --quiet
+Do not print the normal GNU @command{bc} welcome.
+
+@item -v, --version 
+Print the version number and copyright and quit.
+
+@end table
+
+
+@node Basic Elements, Expressions, Introduction, Top
+@chapter Basic Elements
+@menu
+* Numbers::
+* Variables::
+* Comments::
+@end menu
+
+@node Numbers, Variables, Command Line Options, Basic Elements
+@section Numbers
+
+The most basic element in @command{bc} is the number.  Numbers are
+arbitrary precision numbers.  This precision is both in the integer part
+and the fractional part.  All numbers are represented internally in
+decimal and all computation is done in decimal.  (This version truncates
+results from divide and multiply operations.)  There are two attributes
+of numbers, the length and the scale.  The length is the total number of
+significant decimal digits in a number and the scale is the total number
+of decimal digits after the decimal point.  For example, .000001 has a
+length of 6 and scale of 6, while 1935.000 has a length of 7 and a scale
+of 3.
+
+@node Variables, Comments, Numbers, Basic Elements
+@section Variables
+
+Numbers are stored in two types of variables, simple variables and
+arrays.  Both simple variables and array variables are named.  Names
+begin with a letter followed by any number of letters, digits and
+underscores.  All letters must be lower case.  (Full alphanumeric
+names are an extension. In POSIX @command{bc} all names are a single
+lower case letter.)  The type of variable is clear by the context
+because all array variable names will be followed by brackets ( [ ] ).
+
+There are four special variables, @var{scale}, @var{ibase}, @var{obase}, and
+@var{last}.  @var{scale} defines how some operations use digits after the
+decimal point.  The default value of @var{scale} is 0. @var{ibase}
+and @var{obase} define the conversion base for input and output
+numbers.  The default for both input and output is base 10.
+@var{last} (an extension) is a variable that has the value of the last
+printed number.  These will be discussed in further detail where
+appropriate.  All of these variables may have values assigned to them
+as well as used in expressions.
+
+@node Comments, , Variables, Basic Elements
+@section Comments
+
+Comments in @command{bc} start with the characters @code{/*} and end with
+the characters @code{*/}.  Comments may start anywhere and appear as a
+single space in the input.  (This causes comments to delimit other
+input items.  For example, a comment can not be found in the middle of
+a variable name.)  Comments include any newlines (end of line) between
+the start and the end of the comment.
+
+To support the use of scripts for @command{bc}, a single line comment has been
+added as an extension.  A single line comment starts at a @code{#}
+character and continues to the next end of the line.  The end of line
+character is not part of the comment and is processed normally.
+
+@node Expressions, Statements, Basic Elements, Top
+@chapter Expressions
+
+@menu 
+* About Expressions and Special Variables::
+* Basic Expressions::
+* Relational Expressions::
+* Boolean Expressions::
+* Precedence::
+* Special Expressions::
+@end menu
+
+@node About Expressions and Special Variables, Basic Expressions, Expressions, Expressions
+@section About Expressions and Special Variables
+
+The numbers are manipulated by expressions and statements.  Since
+the language was designed to be interactive, statements and expressions
+are executed as soon as possible.  There is no main program.  Instead,
+code is executed as it is encountered.  (Functions, discussed in
+detail later, are defined when encountered.)
+
+A simple expression is just a constant. @command{bc} converts constants
+into internal decimal numbers using the current input base, specified by
+the variable @var{ibase}. (There is an exception in functions.)  The
+legal values of @var{ibase} are 2 through 16.  Assigning a value outside
+this range to @var{ibase} will result in a value of 2 or 16.  Input
+numbers may contain the characters 0-9 and A-F. (Note: They must be
+capitals.  Lower case letters are variable names.)  Single digit numbers
+always have the value of the digit regardless of the value of
+@var{ibase}. (i.e. A = 10.)  For multi-digit numbers, @command{bc}
+changes all input digits greater or equal to @var{ibase} to the value of
+@var{ibase}-1.  This makes the number @code{FFF} always be the largest
+3 digit number of the input base.
+
+Full expressions are similar to many other high level languages.
+Since there is only one kind of number, there are no rules for mixing
+types.  Instead, there are rules on the scale of expressions.  Every
+expression has a scale.  This is derived from the scale of original
+numbers, the operation performed and in many cases, the value of the
+variable @var{scale}. Legal values of the variable @var{scale} are
+0 to the maximum number representable by a C integer.
+
+@node Basic Expressions, Relational Expressions, About Expressions and Special Variables, Expressions
+@section Basic Expressions
+
+In the following descriptions of legal expressions, "expr" refers to a
+complete expression and "@var{var}" refers to a simple or an array variable.
+A simple variable is just a 
+
+@var{name}
+
+and an array variable is specified as 
+
+@var{name}[@var{expr}] 
+
+Unless specifically mentioned the scale of the result is the maximum
+scale of the expressions involved.
+
+@table @code
+@item - expr
+The result is the negation of the expression.
+
+@item ++ @var{var}
+The variable is incremented by one and the new value is the result of
+the expression.
+
+@item -- @var{var}
+The variable
+is decremented by one and the new value is the result of the
+expression.
+
+@item @var{var} ++
+ The result of the expression is the value of
+the variable and then the variable is incremented by one.
+
+@item @var{var} --
+The result of the expression is the value of the variable and then
+the variable is decremented by one.
+
+@item expr + expr
+The result of the expression is the sum of the two expressions.
+
+@item expr - expr
+The result of the expression is the difference of the two expressions.
+
+@item expr * expr
+The result of the expression is the product of the two expressions.
+
+@item expr / expr
+The result of the expression is the quotient of the two expressions.
+The scale of the result is the value of the variable @code{scale}
+
+@item expr % expr
+The result of the expression is the "remainder" and it is computed in the
+following way.  To compute a%b, first a/b is computed to @var{scale}
+digits.  That result is used to compute a-(a/b)*b to the scale of the
+maximum of @var{scale}+scale(b) and scale(a).  If @var{scale} is set
+to zero and both expressions are integers this expression is the
+integer remainder function.
+
+@item expr ^ expr
+The result of the expression is the value of the first raised to the
+second. The second expression must be an integer.  (If the second
+expression is not an integer, a warning is generated and the
+expression is truncated to get an integer value.)  The scale of the
+result is @var{scale} if the exponent is negative.  If the exponent
+is positive the scale of the result is the minimum of the scale of the
+first expression times the value of the exponent and the maximum of
+@var{scale} and the scale of the first expression.  (e.g. scale(a^b)
+= min(scale(a)*b, max(@var{scale}, scale(a))).)  It should be noted
+that expr^0 will always return the value of 1.
+
+@item ( expr )
+This alters the standard precedence to force the evaluation of the
+expression.
+
+@item @var{var} = expr
+The variable is assigned the value of the expression.
+
+@item @var{var} <op>= expr
+This is equivalent to "@var{var} = @var{var} <op> expr" with the
+exception that the "@var{var}" part is evaluated only once.  This can
+make a difference if "@var{var}" is an array.
+@end table
+
+@node Relational Expressions, Boolean Expressions, Basic Expressions, Expressions
+@section Relational Expressions
+
+Relational expressions are a special kind of expression that always
+evaluate to 0 or 1, 0 if the relation is false and 1 if the relation is
+true.  These may appear in any legal expression.  (POSIX @command{bc}
+requires that relational expressions are used only in @code{if},
+@code{while}, and @code{for} statements and that only one relational
+test may be done in them.)  The relational operators are
+
+@table @code
+@item expr1 < expr2
+The result is 1 if expr1 is strictly less than expr2.
+
+@item expr1 <= expr2
+The result is 1 if expr1 is less than or equal to expr2.
+
+@item expr1 > expr2
+The result is 1 if expr1 is strictly greater than expr2.
+
+@item expr1 >= expr2
+The result is 1 if expr1 is greater than or equal to expr2.
+
+@item expr1 == expr2
+The result is 1 if expr1 is equal to expr2.
+
+@item expr1 != expr2
+The result is 1 if expr1 is not equal to expr2.
+@end table
+
+@node Boolean Expressions, Precedence, Relational Expressions, Expressions
+@section Boolean Expressions
+
+Boolean operations are also legal.  (POSIX @command{bc} does NOT have
+boolean operations). The result of all boolean operations are 0 and 1
+(for false and true) as in relational expressions.  The boolean
+operators are:
+
+@table @code
+@item !expr
+The result is 1 if expr is 0.
+
+@item expr && expr
+The result is 1 if both expressions are non-zero.
+
+@item expr || expr
+The result is 1 if either expression is non-zero.
+@end table
+
+@node Precedence, Special Expressions, Boolean Expressions, Expressions
+@section Precedence
+
+The expression precedence is as follows: (lowest to highest)
+
+@example
+|| operator, left associative
+&& operator, left associative
+! operator, nonassociative
+Relational operators, left associative
+Assignment operator, right associative
++ and - operators, left associative
+*, / and % operators, left associative
+^ operator, right associative
+unary - operator, nonassociative
+++ and -- operators, nonassociative
+@end example
+
+This precedence was chosen so that POSIX compliant @command{bc} programs
+will run correctly. This will cause the use of the relational and
+logical operators to have some unusual behavior when used with
+assignment expressions.  Consider the expression:
+
+@example
+a = 3 < 5
+@end example
+
+Most C programmers would assume this would assign the result of "3 <
+5" (the value 1) to the variable "a".  What this does in @command{bc} is
+assign the value 3 to the variable "a" and then compare 3 to 5.  It is
+best to use parentheses when using relational and logical operators
+with the assignment operators.
+
+@node Special Expressions, , Precedence, Expressions
+@section Special Expressions
+
+There are a few more special expressions that are provided in
+@command{bc}.  These have to do with user-defined functions and standard
+functions.  They all appear as
+"@var{name}@code{(}@var{parameters}@code{)}".  @xref{Functions}, for
+user-defined functions.  The standard functions are:
+
+@table @code
+@item length ( expression )
+The value of the length function is the number of significant digits in the
+expression.
+
+@item read ( )
+The @code{read} function (an extension) will read a number from the
+standard input, regardless of where the function occurs.  Beware, this
+can cause problems with the mixing of data and program in the standard
+input.  The best use for this function is in a previously written
+program that needs input from the user, but never allows program code to
+be input from the user.  The value of the @code{read} function is the
+number read from the standard input using the current value of the
+variable @var{ibase} for the conversion base.
+
+@item scale ( expression )
+The value of the @code{scale} function is the number of digits after the
+decimal point in the expression.
+
+@item sqrt ( expression )
+The value of the @code{sqrt} function is the square root of the
+expression.  If the expression is negative, a run time error is
+generated.
+@end table
+
+@node Statements, Functions, Expressions, Top
+@chapter Statements
+
+@menu
+* Pseudo Statements::
+@end menu
+
+Statements (as in most algebraic languages) provide the sequencing of
+expression evaluation.  In @command{bc} statements are executed "as soon
+as possible."  Execution happens when a newline in encountered and there
+is one or more complete statements.  Due to this immediate execution,
+newlines are very important in @command{bc}. In fact, both a semicolon
+and a newline are used as statement separators.  An improperly placed
+newline will cause a syntax error.  Because newlines are statement
+separators, it is possible to hide a newline by using the backslash
+character.  The sequence "\<nl>", where <nl> is the newline appears to
+@command{bc} as whitespace instead of a newline.  A statement list is a
+series of statements separated by semicolons and newlines.  The
+following is a list of @command{bc} statements and what they do: (Things
+enclosed in brackets ( [ ] ) are optional parts of the statement.)
+
+@table @var
+@item expression
+This statement does one of two things.  If the expression starts with
+"<variable> <assignment> ...", it is considered to be an assignment
+statement.  If the expression is not an assignment statement, the
+expression is evaluated and printed to the output.  After the number is
+printed, a newline is printed.  For example, "a=1" is an assignment
+statement and "(a=1)" is an expression that has an embedded assignment.
+All numbers that are printed are printed in the base specified by the
+variable @var{obase}. The legal values for @var{obase} are 2 through
+BC_BASE_MAX (@pxref{Environment Variables}).  For bases 2 through 16,
+the usual method of writing numbers is used.  For bases greater than 16,
+@command{bc} uses a multi-character digit method of printing the numbers
+where each higher base digit is printed as a base 10 number.  The
+multi-character digits are separated by spaces.  Each digit contains the
+number of characters required to represent the base ten value of
+"@var{obase} -1".  Since numbers are of arbitrary precision, some
+numbers may not be printable on a single output line.  These long
+numbers will be split across lines using the "\" as the last character
+on a line.  The maximum number of characters printed per line is 70.
+Due to the interactive nature of @command{bc}, printing a number causes
+the side effect of assigning the printed value to the special variable
+@var{last}. This allows the user to recover the last value printed
+without having to retype the expression that printed the number.
+Assigning to @var{last} is legal and will overwrite the last printed
+value with the assigned value.  The newly assigned value will remain
+until the next number is printed or another value is assigned to
+@var{last}.  (Some installations may allow the use of a single period
+(.) which is not part of a number as a short hand notation for for
+@var{last}.)
+
+@item string
+The string is printed to the output.  Strings start with a double quote
+character and contain all characters until the next double quote character.
+All characters are taken literally, including any newline.  No newline
+character is printed after the string.
+
+@item @code{print} @var{list}
+The @code{print} statement (an extension) provides another method of
+output.  The @var{list} is a list of strings and expressions separated by
+commas.  Each string or expression is printed in the order of the list.
+No terminating newline is printed.  Expressions are evaluated and their
+value is printed and assigned to the variable @code{last}. Strings in
+the print statement are printed to the output and may contain special
+characters.  Special characters start with the backslash character (\e).
+The special characters recognized by @command{bc} are "a" (alert or
+bell), "b" (backspace), "f" (form feed), "n" (newline), "r" (carriage
+return), "q" (double quote), "t" (tab), and "\e" (backslash).  Any other
+character following the backslash will be ignored.
+
+@item @{ statement_list @}
+This is the compound statement.  It allows multiple statements to be
+grouped together for execution.
+
+@item @code{if} ( expression ) statement1 [@code{else} statement2]
+The if statement evaluates the expression and executes statement1 or
+statement2 depending on the value of the expression.  If the expression
+is non-zero, statement1 is executed.  If statement2 is present and
+the value of the expression is 0, then statement2 is executed.  (The
+@code{else} clause is an extension.)
+
+@item @code{while} ( expression ) statement
+The while statement will execute the statement while the expression
+is non-zero.  It evaluates the expression before each execution of
+the statement.   Termination of the loop is caused by a zero
+expression value or the execution of a @code{break} statement.
+
+@item @code{for} ( [expression1] ; [expression2] ; [expression3] ) statement
+The @code{for} statement controls repeated execution of the statement.
+@var{Expression1} is evaluated before the loop.  @var{Expression2} is
+evaluated before each execution of the statement.  If it is non-zero,
+the statement is evaluated.  If it is zero, the loop is terminated.
+After each execution of the statement, @var{expression3} is evaluated
+before the reevaluation of expression2.  If @var{expression1} or
+@var{expression3} are missing, nothing is evaluated at the point they
+would be evaluated.  If @var{expression2} is missing, it is the same as
+substituting the value 1 for @var{expression2}.  (The optional
+expressions are an extension. POSIX @command{bc} requires all three
+expressions.)  The following is equivalent code for the @code{for}
+statement:
+
+@example
+expression1;
+while (expression2) @{
+   statement;
+   expression3;
+@}
+@end example
+
+@item @code{break}
+This statement causes a forced exit of the most recent enclosing @code{while}
+statement or @code{for} statement.
+
+@item @code{continue}
+The @code{continue} statement (an extension)  causes the most recent enclosing
+@code{for} statement to start the next iteration.
+
+@item @code{halt}
+The @code{halt} statement (an extension) is an executed statement that
+causes the @command{bc} processor to quit only when it is executed.  For
+example, "if (0 == 1) halt" will not cause @command{bc} to terminate
+because the @code{halt} is not executed.
+
+@item @code{return}
+Return the value 0 from a function.  (@xref{Functions}.)
+
+@item @code{return} ( expression )
+Return the value of the expression from a function.  (@xref{Functions}.)
+As an extension, the parenthesis are not required.
+@end table
+
+@node Pseudo Statements, , Statements, Statements
+@section Pseudo Statements
+
+These statements are not statements in the traditional sense.  They are
+not executed statements.  Their function is performed at "compile" time.
+
+@table @code
+@item limits
+Print the local limits enforced by the local version of @command{bc}.  This
+is an extension.
+
+@item quit
+When the @code{quit} statement is read, the @command{bc} processor
+is terminated, regardless of where the @code{quit} statement is found.  For
+example, "if (0 == 1) quit" will cause @command{bc} to terminate.
+
+@item warranty
+Print a longer warranty notice.  This is an extension.
+@end table
+
+@node Functions, Examples, Statements, Top
+@chapter Functions
+
+@menu
+* Math Library Functions::
+@end menu
+
+Functions provide a method of defining a computation that can be
+executed later.  Functions in @command{bc} always compute a value and
+return it to the caller.  Function definitions are "dynamic" in the
+sense that a function is undefined until a definition is encountered in
+the input.  That definition is then used until another definition
+function for the same name is encountered.  The new definition then
+replaces the older definition.  A function is defined as follows:
+
+@example
+@code{define} @var{name} @code{(} @var{parameters} @code{)} @code{@{} @var{newline}
+    @var{auto_list   statement_list} @code{@}}
+@end example
+
+A function call is just an expression of the form
+"@code{name} @code{(}@var{parameters}@code{)}".
+
+Parameters are numbers or arrays (an extension).  In the function definition,
+zero or more parameters are defined by listing their names separated by
+commas.  All parameters  are call by value parameters.
+Arrays are specified in the parameter definition by
+the notation "@var{name}@code{[ ]}".   In the function call, actual parameters
+are full expressions for number parameters.  The same notation is used
+for passing arrays as for defining array parameters.  The named array is
+passed by value to the function.  Since function definitions are dynamic,
+parameter numbers and types are checked when a function is called.  Any
+mismatch in number or types of parameters will cause a runtime error.
+A runtime error will also occur for the call to an undefined function.
+
+The @var{auto_list} is an optional list of variables that are for
+"local" use.  The syntax of the auto list (if present) is "@code{auto}
+@var{name}, ... ;".  (The semicolon is optional.)  Each @var{name} is
+the name of an auto variable.  Arrays may be specified by using the
+same notation as used in parameters.  These variables have their
+values pushed onto a stack at the start of the function.  The
+variables are then initialized to zero and used throughout the
+execution of the function.  At function exit, these variables are
+popped so that the original value (at the time of the function call)
+of these variables are restored.  The parameters are really auto
+variables that are initialized to a value provided in the function
+call.  
+Auto variables are different than traditional local variables
+because if function A calls function B, B may access function
+A's auto variables by just using the same name, unless function B has
+called them auto variables.  Due to the fact that auto variables and
+parameters are pushed onto a stack, @command{bc} supports recursive functions.
+
+The function body is a list of @command{bc} statements.  Again, statements
+are separated by semicolons or newlines.  Return statements cause the
+termination of a function and the return of a value.  There are two
+versions of the return statement.  The first form, "@code{return}", returns
+the value 0 to the calling expression.  The second form, 
+"@code{return} ( @var{expression} )", computes the value of the expression
+and returns that value to the calling expression.  There is an implied
+"@code{return} (0)" at the end of every function.  This allows a function
+to terminate and return 0 without an explicit @code{return} statement.
+
+Functions also change the usage of the variable @var{ibase}.  All
+constants in the function body will be converted using the value of
+@var{ibase} at the time of the function call.  Changes of @var{ibase}
+will be ignored during the execution of the function except for the
+standard function @code{read}, which will always use the current value
+of @var{ibase} for conversion of numbers.
+
+Several extensions have been added to functions.  First, the format of
+the definition has been slightly relaxed.  The standard requires the
+opening brace be on the same line as the @code{define} keyword and all
+other parts must be on following lines.  This version of @command{bc}
+will allow any number of newlines before and after the opening brace of
+the function.  For example, the following definitions are legal.
+
+@example
+   define d (n) @{ return (2*n); @}
+   define d (n)
+       @{ return (2*n); @}
+@end example
+
+Functions may be defined as @code{void}.  A void
+funtion returns no value and thus may not be used in any place that needs
+a value.  A void function does not produce any output when called by itself
+on an input line.  The key word @code{void} is placed between the key word
+@code{define} and the function name.  For example, consider the following
+session.
+
+@example
+define py (y) @{ print "--->", y, "<---", "\n"; @}
+define void px (x) @{ print "--->", x, "<---", "\n"; @}
+py(1)
+--->1<---
+0
+px(1)
+--->1<---
+@end example
+
+Since @code{py} is not a void function, the call of @code{py(1)} prints
+the desired output and then prints a second line that is the value of
+the function.  Since the value of a function that is not given an
+explicit return statement is zero, the zero is printed.  For @code{px(1)},
+no zero is printed because the function is a void function.
+
+Also, call by variable for arrays was added.  To declare a
+call by variable array, the declaration of the array parameter in the
+function definition looks like "@code{*}@var{name}@code{[]}".  The call
+to the function remains the same as call by value arrays.
+
+@node Math Library Functions, , Functions, Functions
+@section Math Library Functions
+
+If @command{bc} is invoked with the @code{-l} option, a math library is
+preloaded and the default @var{scale} is set to 20.  The math functions will
+calculate their results to the scale set at the time of their call.  The
+math library defines the following functions:
+
+@table @code
+@item s (@var{x})
+The sine of @var{x}, @var{x} is in radians.
+
+@item c (@var{x})
+The cosine of @var{x}, @var{x} is in radians.
+
+@item a (@var{x})
+The arctangent of @var{x}, arctangent returns radians.
+
+@item l (@var{x})
+The natural logarithm of @var{x}.
+
+@item e (@var{x})
+The exponential function of raising @var{e} to the value @var{x}.
+
+@item j (@var{n,x})
+The Bessel function of integer order @var{n} of @var{x}.
+@end table
+
+@node Examples, Readline and Libedit Options, Functions, Top
+@chapter Examples
+
+In /bin/sh,  the following will assign the value of "pi" to the shell
+variable @var{pi}.
+@example
+
+pi=$(echo "scale=10; 4*a(1)" | bc -l)
+
+@end example
+
+The following is the definition of the exponential function used in the
+math library.  This function is written in POSIX @command{bc}.
+
+@example
+
+scale = 20
+
+/* Uses the fact that e^x = (e^(x/2))^2
+   When x is small enough, we use the series:
+     e^x = 1 + x + x^2/2! + x^3/3! + ...
+*/
+
+define e(x) @{
+  auto  a, d, e, f, i, m, v, z
+
+  /* Check the sign of x. */
+  if (x<0) @{
+    m = 1
+    x = -x
+  @} 
+
+  /* Precondition x. */
+  z = scale;
+  scale = 4 + z + .44*x;
+  while (x > 1) @{
+    f += 1;
+    x /= 2;
+  @}
+
+  /* Initialize the variables. */
+  v = 1+x
+  a = x
+  d = 1
+
+  for (i=2; 1; i++) @{
+    e = (a *= x) / (d *= i)
+    if (e == 0) @{
+      if (f>0) while (f--)  v = v*v;
+      scale = z
+      if (m) return (1/v);
+      return (v/1);
+    @}
+    v += e
+  @}
+@}
+
+@end example
+
+The following is code that uses the extended features of @command{bc} to
+implement a simple program for calculating checkbook balances.  This
+program is best kept in a file so that it can be used many times 
+without having to retype it at every use.
+
+@example
+
+scale=2
+print "\nCheck book program\n!"
+print "  Remember, deposits are negative transactions.\n"
+print "  Exit by a 0 transaction.\n\n"
+
+print "Initial balance? "; bal = read()
+bal /= 1
+print "\n"
+while (1) @{
+  "current balance = "; bal
+  "transaction? "; trans = read()
+  if (trans == 0) break;
+  bal -= trans
+  bal /= 1
+@}
+quit
+
+@end example
+
+
+The following is the definition of the recursive factorial function.
+
+@example
+
+define f (x) @{
+  if (x <= 1) return (1);
+  return (f(x-1) * x);
+@}
+
+@end example
+
+@node Readline and Libedit Options, Comparison with Other Implementations, Examples, Top
+@chapter Readline and Libedit Options
+
+GNU @command{bc} can be compiled (via a configure option) to use the GNU
+@command{readline} input editor library or the BSD @command{libedit}
+library.  This allows the user to do
+more editing of lines before sending them to @command{bc}.  It also
+allows for a history of previous lines typed.  When this option is
+selected, @command{bc} has one more special variable.  This special
+variable, @var{history} is the number of lines of history retained.  A
+value of -1 means that an unlimited number of history lines are
+retained.  This is the default value.  Setting the value of
+@var{history} to a positive number restricts the number of history lines
+to the number given.  The value of 0 disables the history feature.  For
+more information, read the user manuals for the GNU @command{readline},
+@command{history} and BSD @command{libedit} libraries.  One can not
+enable both @command{readline} and @command{libedit} at the same time.
+
+@node Comparison with Other Implementations, Limits, Readline and Libedit Options, Top
+@chapter Comparison with Other Implementations
+
+This version of @command{bc} was implemented from the POSIX P1003.2/D11
+draft and contains several differences and extensions relative to the
+draft and traditional implementations.  It is not implemented in the
+traditional way using @command{dc}.  This version is a single process
+which parses and runs a byte code translation of the program.  There is
+an "undocumented" option (-c) that causes the program to output the byte
+code to the standard output instead of running it.  It was mainly used
+for debugging the parser and preparing the math library.
+
+A major source of differences is extensions, where a feature is extended
+to add more functionality and additions, where new features are added.
+The following is the list of differences and extensions.
+
+@table @var
+
+@item LANG environment
+This version does not conform to the POSIX standard in the processing
+of the LANG environment variable and all environment variables starting
+with LC_.
+
+@item names
+Traditional and POSIX @command{bc}
+have single letter names for functions, variables and arrays.  They have
+been extended to be multi-character names that start with a letter and
+may contain letters, numbers and the underscore character.
+
+@item Strings
+Strings are not allowed to contain NUL characters.  POSIX says all characters
+must be included in strings.
+
+@item last
+POSIX @command{bc} does not have a \fBlast variable.  Some implementations
+of @command{bc} use the period (.) in a similar way.  
+
+@item comparisons
+POSIX @command{bc} allows comparisons only in the @code{if} statement,
+the @code{while} statement, and the second expression of the @code{for}
+statement.  Also, only one relational operation is allowed in each of
+those statements.
+
+@item if statement, else clause
+POSIX @command{bc} does not have an @code{else} clause.
+
+@item for statement
+POSIX @command{bc} requires all expressions to be present in the
+@code{for} statement.
+
+@item &&, ||, !
+POSIX @command{bc} does not have the logical operators.
+
+@item read function
+POSIX @command{bc} does not have a @code{read} function.
+
+@item print statement
+POSIX @command{bc} does not have a @code{print} statement.
+
+@item continue statement
+POSIX @command{bc} does not have a continue statement.
+
+@item array parameters
+POSIX @command{bc} does not (currently) support array parameters in full.
+The POSIX grammar allows for arrays in function definitions, but does
+not provide a method to specify an array as an actual parameter.  (This
+is most likely an oversight in the grammar.)  Traditional implementations
+of @command{bc} have only call by value array parameters.
+
+@item function format
+POSIX @command{bc} requires the opening brace on the same line as the 
+@code{define} key word and the @code{auto} statement on the next line.
+
+@item =+, =-, =*, =/, =%, =^
+POSIX @command{bc} does not require these "old style" assignment
+operators to be defined.  This version may allow these "old style"
+assignments.  Use the @code{limits} statement to see if the installed
+version supports them.  If it does support the "old style" assignment
+operators, the statement "a =- 1" will decrement @code{a} by 1 instead
+of setting @code{a} to the value -1.
+
+@item spaces in numbers
+Other implementations of @command{bc} allow spaces in numbers.  For example,
+"x=1 3" would assign the value 13 to the variable x.  The same statement
+would cause a syntax error in this version of @command{bc}.
+
+@item errors and execution
+This implementation varies from other implementations in terms of what
+code will be executed when syntax and other errors are found in the
+program.  If a syntax error is found in a function definition, error
+recovery tries to find the beginning of a statement and continue to
+parse the function.  Once a syntax error is found in the function, the
+function will not be callable and becomes undefined.
+Syntax errors in the interactive execution code will invalidate the
+current execution block.  The execution block is terminated by an
+end of line that appears after a complete sequence of statements.
+For example, 
+
+@example
+a = 1
+b = 2
+@end example
+
+has two execution blocks and
+
+@example
+@{ a = 1
+  b = 2 @}
+@end example
+
+has one execution block.  Any runtime error will terminate the execution
+of the current execution block.  A runtime warning will not terminate the
+current execution block.
+
+@item Interrupts
+During an interactive session, the SIGINT signal (usually generated by
+the control-C character from the terminal) will cause execution of the
+current execution block to be interrupted.  It will display a "runtime"
+error indicating which function was interrupted.  After all runtime
+structures have been cleaned up, a message will be printed to notify the
+user that @command{bc} is ready for more input.  All previously defined
+functions remain defined and the value of all non-auto variables are the
+value at the point of interruption.  All auto variables and function
+parameters are removed during the clean up process.  During a
+non-interactive session, the SIGINT signal will terminate the entire run
+of @command{bc}.
+@end table
+
+@node Limits, Environment Variables, Comparison with Other Implementations, Top
+@chapter Limits
+
+The following are the limits currently in place for this @command{bc}
+processor.  Some of them may have been changed by an installation.  Use
+the @code{limits} statement to see the actual values.
+
+@table @code
+
+@item BC_BASE_MAX
+The maximum output base is currently set at 999.  The maximum input base
+is 16.
+
+@item BC_DIM_MAX
+This is currently an arbitrary limit of 65535 as distributed.  Your
+installation may be different.
+
+@item BC_SCALE_MAX
+The number of digits after the decimal point is limited to INT_MAX digits.
+Also, the number of digits before the decimal point is limited to INT_MAX
+digits.
+
+@item BC_STRING_MAX
+The limit on the number of characters in a string is INT_MAX characters.
+
+@item exponent
+The value of the exponent in the raise operation (^) is limited to LONG_MAX.
+
+@item multiply
+The multiply routine may yield incorrect results if a number
+has more than LONG_MAX / 90 total digits.  For 32 bit longs, this number is
+23,860,929 digits.
+
+@item variable names
+The current limit on the number of unique names is 32767 for each of
+simple variables, arrays and functions.
+@end table
+
+@node Environment Variables, , Limits, Top
+@chapter Environment Variables
+
+The following environment variables are processed by @command{bc}:
+
+@table @code
+
+
+@item POSIXLY_CORRECT
+This is the same as the -s option (@pxref{Command Line Options}).
+
+@item BC_ENV_ARGS
+This is another mechanism to get arguments to @command{bc}.  The format
+is the same as the command line arguments.  These arguments are
+processed first, so any files listed in the environment arguments are
+processed before any command line argument files.  This allows the user
+to set up "standard" options and files to be processed at every
+invocation of @command{bc}.  The files in the environment variables
+would typically contain function definitions for functions the user
+wants defined every time @command{bc} is run.
+
+@item BC_LINE_LENGTH
+This should be an integer specifying the number of characters in an
+output line for numbers. This includes the backslash and newline
+characters for long numbers. As an extension, the value of zero disables the 
+multi-line feature.  Any other value of this variable that is less than
+3 sets the line length to 70.
+@end table
+
+@contents
+@bye
diff --git a/doc/dc.1 b/doc/dc.1
new file mode 100644 (file)
index 0000000..3c67bd9
--- /dev/null
+++ b/doc/dc.1
@@ -0,0 +1,507 @@
+.\"
+.\" dc.1 - the *roff document processor source for the dc manual
+.\"
+.\" This file is part of GNU dc.
+.\" Copyright (C) 1994, 1997, 1998, 2000, 2001, 2005, 2006 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 of the License , or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; see the file COPYING.  If not, write to:
+.\"   The Free Software Foundation, Inc.
+.\"   51 Franklin Street, Fifth Floor
+.\"   Boston, MA 02110-1301  USA
+.\"
+.TH dc 1 "2006-06-11" "GNU Project"
+.ds dc \fIdc\fP
+.ds Dc \fIdc\fP
+.SH NAME
+dc \- an arbitrary precision calculator
+.SH SYNOPSIS
+dc [-V] [--version] [-h] [--help]
+   [-e scriptexpression] [--expression=scriptexpression]
+   [-f scriptfile] [--file=scriptfile]
+   [file ...]
+.SH DESCRIPTION
+.PP
+\*(Dc is a reverse-polish desk calculator which supports
+unlimited precision arithmetic.
+It also allows you to define and call macros.
+Normally \*(dc reads from the standard input;
+if any command arguments are given to it, they are filenames,
+and \*(dc reads and executes the contents of the files before reading
+from standard input.
+All normal output is to standard output;
+all error output is to standard error.
+.PP
+A reverse-polish calculator stores numbers on a stack.
+Entering a number pushes it on the stack.
+Arithmetic operations pop arguments off the stack and push the results.
+.PP
+To enter a number in
+.IR dc ,
+type the digits
+(using upper case letters
+.I A
+through
+.I F
+as "digits" when working
+with input bases greater than ten),
+with an optional decimal point.
+Exponential notation is not supported.
+To enter a negative number,
+begin the number with ``_''.
+``-'' cannot be used for this,
+as it is a binary operator for subtraction instead.
+To enter two numbers in succession,
+separate them with spaces or newlines.
+These have no meaning as commands.
+.SH OPTIONS
+\*(Dc may be invoked with the following command-line options:
+.TP
+.B -V
+.TP
+.B --version
+Print out the version of \*(dc that is being run and a copyright notice,
+then exit.
+.TP
+.B -h
+.TP
+.B --help
+Print a usage message briefly summarizing these command-line options
+and the bug-reporting address,
+then exit.
+.TP
+.B -e \fIscript\fP
+.TP
+.BI --expression= script
+Add the commands in
+.I script
+to the set of commands to be run while processing the input.
+.TP
+.B -f \fIscript-file\fP
+.TP
+.BI --file= script-file
+Add the commands contained in the file
+.I script-file
+to the set of commands to be run while processing the input.
+.PP
+If any command-line parameters remain after processing the above,
+these parameters are interpreted as the names of input files to
+be processed.
+A file name of
+.B -
+refers to the standard input stream.
+The standard input will processed if no script files or
+expressions are specified.
+.PD
+.SH
+Printing Commands
+.TP
+.B p
+Prints the value on the top of the stack,
+without altering the stack.
+A newline is printed after the value.
+.TP
+.B n
+Prints the value on the top of the stack, popping it off,
+and does not print a newline after.
+.TP
+.B P
+Pops off the value on top of the stack.
+If it it a string, it is simply printed without a trailing newline.
+Otherwise it is a number, and the integer portion of its absolute
+value is printed out as a "base (UCHAR_MAX+1)" byte stream.
+Assuming that (UCHAR_MAX+1) is 256
+(as it is on most machines with 8-bit bytes),
+the sequence \fBKSK0k1/_1Ss [ls*]Sxd0>x
+[256~Ssd0<x]dsxxsx[q]Sq[Lsd0>qaPlxx]
+dsxxsx0sqLqsxLxLK+k\fP
+could also accomplish this function.
+(Much of the complexity of the above native-dc code is due
+to the ~ computing the characters backwards,
+and the desire to ensure that all registers wind up back
+in their original states.)
+.TP
+.B f
+Prints the entire contents of the stack
+.ig
+and the contents of all of the registers,
+..
+without altering anything.
+This is a good command to use if you are lost or want
+to figure out what the effect of some command has been.
+.PD
+.SH
+Arithmetic
+.TP
+.B +
+Pops two values off the stack, adds them,
+and pushes the result.
+The precision of the result is determined only
+by the values of the arguments,
+and is enough to be exact.
+.TP
+.B -
+Pops two values,
+subtracts the first one popped from the second one popped,
+and pushes the result.
+.TP
+.B *
+Pops two values, multiplies them, and pushes the result.
+The number of fraction digits in the result depends on
+the current precision value and the number of fraction
+digits in the two arguments.
+.TP
+.B /
+Pops two values,
+divides the second one popped from the first one popped,
+and pushes the result.
+The number of fraction digits is specified by the precision value.
+.TP
+.B %
+Pops two values,
+computes the remainder of the division that the
+.B /
+command would do,
+and pushes that.
+The value computed is the same as that computed by
+the sequence \fBSd dld/ Ld*-\fP .
+.TP
+.B ~
+Pops two values,
+divides the second one popped from the first one popped.
+The quotient is pushed first, and the remainder is pushed next.
+The number of fraction digits used in the division
+is specified by the precision value.
+(The sequence \fBSdSn lnld/ LnLd%\fP could also accomplish
+this function, with slightly different error checking.)
+.TP
+.B ^
+Pops two values and exponentiates,
+using the first value popped as the exponent
+and the second popped as the base.
+The fraction part of the exponent is ignored.
+The precision value specifies the number of fraction
+digits in the result.
+.TP
+.B |
+Pops three values and computes a modular exponentiation.
+The first value popped is used as the reduction modulus;
+this value must be a non-zero number,
+and should be an integer.
+The second popped is used as the exponent;
+this value must be a non-negative number,
+and any fractional part of this exponent will be ignored.
+The third value popped is the base which gets exponentiated,
+which should be an integer.
+For small integers this is like the sequence \fBSm^Lm%\fP,
+but, unlike \fB^\fP, this command will work with arbitrarily large exponents.
+.TP
+.B v
+Pops one value,
+computes its square root,
+and pushes that.
+The precision value specifies the number of fraction digits in the result.
+.PP
+Most arithmetic operations are affected by the ``precision value'',
+which you can set with the
+.B k
+command.
+The default precision value is zero,
+which means that all arithmetic except for
+addition and subtraction produces integer results.
+.SH
+Stack Control
+.TP
+.B c
+Clears the stack, rendering it empty.
+.TP
+.B d
+Duplicates the value on the top of the stack,
+pushing another copy of it.
+Thus, ``4d*p'' computes 4 squared and prints it.
+.TP
+.B r
+Reverses the order of (swaps) the top two values on the stack.
+(This can also be accomplished with the sequence \fBSaSbLaLb\fP.)
+.SH
+Registers
+.PP
+\*(Dc provides at least 256 memory registers,
+each named by a single character.
+You can store a number or a string in a register and retrieve it later.
+.TP
+.BI s r
+Pop the value off the top of the stack and store
+it into register
+.IR r .
+.TP
+.BI l r
+Copy the value in register
+.I r
+and push it onto the stack.
+This does not alter the contents of
+.IR r .
+.PP
+Each register also contains its own stack.
+The current register value is the top of the register's stack.
+.TP
+.BI S r
+Pop the value off the top of the (main) stack and
+push it onto the stack of register
+.IR r .
+The previous value of the register becomes inaccessible.
+.TP
+.BI L r
+Pop the value off the top of register
+.IR r 's
+stack and push it onto the main stack.
+The previous value
+in register
+.IR r 's
+stack, if any,
+is now accessible via the
+.BI l r
+command.
+.ig
+.PP
+The
+.B f
+command prints a list of all registers that have contents stored in them,
+together with their contents.
+Only the current contents of each register
+(the top of its stack)
+is printed.
+..
+.SH
+Parameters
+.PP
+\*(Dc has three parameters that control its operation:
+the precision, the input radix, and the output radix.
+The precision specifies the number
+of fraction digits to keep in the result of most arithmetic operations.
+The input radix controls the interpretation of numbers typed in;
+all numbers typed in use this radix.
+The output radix is used for printing numbers.
+.PP
+The input and output radices are separate parameters;
+you can make them unequal,
+which can be useful or confusing.
+The input radix must be between 2 and 16 inclusive.
+The output radix must be at least 2.
+The precision must be zero or greater.
+The precision is always measured in decimal digits,
+regardless of the current input or output radix.
+.TP
+.B i
+Pops the value off the top of the stack
+and uses it to set the input radix.
+.TP
+.B o
+Pops the value off the top of the stack
+and uses it to set the output radix.
+.TP
+.B k
+Pops the value off the top of the stack
+and uses it to set the precision.
+.TP
+.B I
+Pushes the current input radix on the stack.
+.TP
+.B O
+Pushes the current output radix on the stack.
+.TP
+.B K
+Pushes the current precision on the stack.
+.SH
+Strings
+.PP
+\*(Dc has a limited ability to operate on strings
+as well as on numbers;
+the only things you can do with strings are
+print them and execute them as macros
+(which means that the contents of the string are processed as
+\*(dc commands).
+All registers and the stack can hold strings,
+and \*(dc always knows whether any given object is a string or a number.
+Some commands such as arithmetic operations demand numbers
+as arguments and print errors if given strings.
+Other commands can accept either a number or a string;
+for example, the
+.B p
+command can accept either and prints the object
+according to its type.
+.TP
+.BI [ characters ]
+Makes a string containing
+.I characters
+(contained between balanced
+.B [
+and
+.B ]
+characters),
+and pushes it on the stack.
+For example,
+.B [foo]P
+prints the characters
+.B foo
+(with no newline).
+.TP
+.B a
+The top-of-stack is popped.
+If it was a number, then the low-order byte of this number
+is converted into a string and pushed onto the stack.
+Otherwise the top-of-stack was a string,
+and the first character of that string is pushed back.
+.TP
+.B x
+Pops a value off the stack and executes it as a macro.
+Normally it should be a string;
+if it is a number,
+it is simply pushed back onto the stack.
+For example,
+.B [1p]x
+executes the macro
+.B 1p
+which pushes
+.B 1
+on the stack and prints
+.B 1
+on a separate line.
+.PP
+Macros are most often stored in registers;
+.B [1p]sa
+stores a macro to print
+.B 1
+into register
+.BR a ,
+and
+.B lax
+invokes this macro.
+.TP
+.BI > r
+Pops two values off the stack and compares them
+assuming they are numbers,
+executing the contents of register
+.I r
+as a macro if the original top-of-stack
+is greater.
+Thus,
+.B 1 2>a
+will invoke register
+.BR a 's
+contents and
+.B 2 1>a
+will not.
+.TP
+.BI !> r
+Similar but invokes the macro if the original top-of-stack is
+not greater than (less than or equal to) what was the second-to-top.
+.TP
+.BI < r
+Similar but invokes the macro if the original top-of-stack is less.
+.TP
+.BI !< r
+Similar but invokes the macro if the original top-of-stack is
+not less than (greater than or equal to) what was the second-to-top.
+.TP
+.BI = r
+Similar but invokes the macro if the two numbers popped are equal.
+.TP
+.BI != r
+Similar but invokes the macro if the two numbers popped are not equal.
+.ig
+This can also be validly used to compare two strings for equality.
+..
+.TP
+.B ?
+Reads a line from the terminal and executes it.
+This command allows a macro to request input from the user.
+.TP
+.B q
+exits from a macro and also from the macro which invoked it.
+If called from the top level,
+or from a macro which was called directly from the top level,
+the
+.B q
+command will cause \*(dc to exit.
+.TP
+.B Q
+Pops a value off the stack and uses it as a count
+of levels of macro execution to be exited.
+Thus,
+.B 3Q
+exits three levels.
+The
+.B Q
+command will never cause \*(dc to exit.
+.SH
+Status Inquiry
+.TP
+.B Z
+Pops a value off the stack,
+calculates the number of digits it has
+(or number of characters, if it is a string)
+and pushes that number.
+The digit count for a number does
+.I not
+include any leading zeros,
+even if those appear to the right of the radix point.
+.TP
+.B X
+Pops a value off the stack,
+calculates the number of fraction digits it has,
+and pushes that number.
+For a string,
+the value pushed is
+.\" -1.
+0.
+.TP
+.B z
+Pushes the current stack depth:
+the number of objects on the stack before the execution of the
+.B z
+command.
+.SH
+Miscellaneous
+.TP
+.B !
+Will run the rest of the line as a system command.
+Note that parsing of the !<, !=, and !> commands take precedence,
+so if you want to run a command starting with <, =, or > you will
+need to add a space after the !.
+.TP
+.B #
+Will interpret the rest of the line as a comment.
+.TP
+.BI : r
+Will pop the top two values off of the stack.
+The old second-to-top value will be stored in the array
+.IR r ,
+indexed by the old top-of-stack value.
+.TP
+.BI ; r
+Pops the top-of-stack and uses it as an index into
+the array
+.IR r .
+The selected value is then pushed onto the stack.
+.P
+Note that each stacked instance of a register has its own
+array associated with it.
+Thus \fB1 0:a 0Sa 2 0:a La 0;ap\fP will print 1,
+because the 2 was stored in an instance of 0:a that
+was later popped.
+.SH
+BUGS
+.PP
+Email bug reports to
+.BR bug-dc@gnu.org .
diff --git a/doc/dc.info b/doc/dc.info
new file mode 100644 (file)
index 0000000..98f92dd
--- /dev/null
@@ -0,0 +1,479 @@
+This is dc.info, produced by makeinfo version 4.8 from dc.texi.
+
+START-INFO-DIR-ENTRY
+* dc: (dc).                   Arbitrary precision RPN "Desktop Calculator".
+END-INFO-DIR-ENTRY
+
+   This file documents `dc', an arbitrary precision calculator.
+
+   Published by the Free Software Foundation, Inc.  51 Franklin Street,
+Fifth Floor Boston, MA 02110-1301  USA
+
+   Copyright (C) 1984, 1994, 1997, 1998, 2000, 2005, 2006 Free Software
+Foundation, Inc.
+
+   Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+   Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+   Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+\1f
+File: dc.info,  Node: Top,  Next: Introduction,  Prev: (dir),  Up: (dir)
+
+* Menu:
+
+* Introduction::                Introduction
+* Invocation::                  Invocation
+* Printing Commands::           Printing Commands
+* Arithmetic::                  Arithmetic
+* Stack Control::               Stack Control
+* Registers::                   Registers
+* Parameters::                  Parameters
+* Strings::                     Strings
+* Status Inquiry::              Status Inquiry
+* Miscellaneous::               Other commands
+* Reporting bugs::              Reporting bugs
+
+\1f
+File: dc.info,  Node: Introduction,  Next: Invocation,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+`dc' is a reverse-polish desk calculator which supports unlimited
+precision arithmetic.  It also allows you to define and call macros.
+Normally `dc' reads from the standard input; if any command arguments
+are given to it, they are filenames, and `dc' reads and executes the
+contents of the files instead of reading from standard input.  All
+normal output is to standard output; all error messages are written to
+standard error.
+
+   To exit, use `q'.  `C-c' (or whatever other keystroke your system
+uses to generate a `SIGINT') does not exit; it is used to abort macros
+that are looping, etc.
+
+   A reverse-polish calculator stores numbers on a stack.  Entering a
+number pushes it on the stack.  Arithmetic operations pop arguments off
+the stack and push the results.
+
+   To enter a number in `dc', type the digits (using upper case letters
+`A' through `F' as "digits" when working with input bases greater than
+ten), with an optional decimal point.  Exponential notation is not
+supported.  To enter a negative number, begin the number with `_'.  `-'
+cannot be used for this, as it is a binary operator for subtraction
+instead.  To enter two numbers in succession, separate them with spaces
+or newlines; these have no meaning as commands.
+
+\1f
+File: dc.info,  Node: Invocation,  Next: Printing Commands,  Prev: Introduction,  Up: Top
+
+2 Invocation
+************
+
+`dc' may be invoked with the following command-line options:
+`-e EXPR'
+
+`--expression=EXPR'
+     Evaluate EXPR as `dc' commands.
+
+`-f FILE'
+
+`--file=FILE'
+     Read and evaluate `dc' commands from FILE.
+
+`-h'
+
+`--help'
+     Print a usage message summarizing the command-line options, then
+     exit.
+
+`-V'
+
+`--version'
+     Print the version information for this program, then exit.
+
+   If any command-line parameters remain after processing the options,
+these parameters are interpreted as additional FILEs whose contents are
+read and evaluated.  A file name of `-' refers to the standard input
+stream.  If no `-e' option was specified, and no files were specified,
+then the standard input will be read for commands to evaluate.
+
+\1f
+File: dc.info,  Node: Printing Commands,  Next: Arithmetic,  Prev: Invocation,  Up: Top
+
+3 Printing Commands
+*******************
+
+`p'
+     Prints the value on the top of the stack, without altering the
+     stack.  A newline is printed after the value.
+
+`n'
+     Prints the value on the top of the stack, popping it off, and does
+     not print a newline after.  (This command is a GNU extension.)
+
+`P'
+     Pops off the value on top of the stack.  If it it a string, it is
+     simply printed without a trailing newline.  Otherwise it is a
+     number, and the integer portion of its absolute value is printed
+     out as a "base (UCHAR_MAX+1)" byte stream.  Assuming that
+     (UCHAR_MAX+1) is 256 (as it is on most machines with 8-bit bytes),
+     the sequence `KSK0k1/ _1Ss[ls*]Sxd0>x [256~Ssd0<x]dsxx
+     sx[q]Sq[Lsd0>qaPlxx]dsxx sx0sqLqsxLxLK+k' could also accomplish
+     this function.  (Much of the complexity of the above native-dc
+     code is due to the ~ computing the characters backwards, and the
+     desire to ensure that all registers wind up back in their original
+     states.)  (Details of the behavior with a number are a GNU
+     extension.  Traditional `dc' happened to "support" similar
+     functionality for a limited range of inputs as an accidental
+     side-effect of its internal representation of numbers.)
+
+`f'
+     Prints the entire contents of the stack without altering anything.
+     This is a good command to use if you are lost or want to figure
+     out what the effect of some command has been.
+
+   All numeric output is split to fit within 70 columns, by default.
+When a number is broken up in this way, the split is indicated by a "\"
+at the end of the to-be-continued output lines.  The column width at
+which output is split can be overridden by setting the DC_LINE_LENGTH
+environment variable to the desired width.  A DC_LINE_LENGTH of 0
+(zero) disables the line-split feature altogether.  Invalid values of
+DC_LINE_LENGTH are silently ignored.  (The DC_LINE_LENGTH variable is a
+GNU extension.)
+
+\1f
+File: dc.info,  Node: Arithmetic,  Next: Stack Control,  Prev: Printing Commands,  Up: Top
+
+4 Arithmetic
+************
+
+`+'
+     Pops two values off the stack, adds them, and pushes the result.
+     The precision of the result is determined only by the values of
+     the arguments, and is enough to be exact.
+
+`-'
+     Pops two values, subtracts the first one popped from the second
+     one popped, and pushes the result.
+
+`*'
+     Pops two values, multiplies them, and pushes the result.  The
+     number of fraction digits in the result is the largest of the
+     precision value, the number of fraction digits in the multiplier,
+     or the number of fraction digits in the multiplicand; but in no
+     event exceeding the number of digits required for an exact result.
+
+`/'
+     Pops two values, divides the second one popped from the first one
+     popped, and pushes the result.  The number of fraction digits is
+     specified by the precision value.
+
+`%'
+     Pops two values, computes the remainder of the division that the
+     `/' command would do, and pushes that.  The value computed is the
+     same as that computed by the sequence `Sd dld/ Ld*-' .
+
+`~'
+     Pops two values, divides the second one popped from the first one
+     popped.  The quotient is pushed first, and the remainder is pushed
+     next.  The number of fraction digits used in the division is
+     specified by the precision value.  (The sequence `SdSn lnld/
+     LnLd%' could also accomplish this function, with slightly
+     different error checking.)  (This command is a GNU extension.)
+
+`^'
+     Pops two values and exponentiates, using the first value popped as
+     the exponent and the second popped as the base.  The fraction part
+     of the exponent is ignored.  The precision value specifies the
+     number of fraction digits in the result.
+
+`|'
+     Pops three values and computes a modular exponentiation.  The
+     first value popped is used as the reduction modulus; this value
+     must be a non-zero number, and the result may not be accurate if
+     the modulus is not an integer.  The second popped is used as the
+     exponent; this value must be a non-negative number, and any
+     fractional part of this exponent will be ignored.  The third value
+     popped is the base which gets exponentiated, which should be an
+     integer.  For small integers this is like the sequence `Sm^Lm%',
+     but, unlike `^', this command will work with arbritrarily large
+     exponents.  (This command is a GNU extension.)
+
+`v'
+     Pops one value, computes its square root, and pushes that.  The
+     precision value specifies the number of fraction digits in the
+     result.
+
+   Most arithmetic operations are affected by the _precision value_,
+which you can set with the `k' command.  The default precision value is
+zero, which means that all arithmetic except for addition and
+subtraction produces integer results.
+
+\1f
+File: dc.info,  Node: Stack Control,  Next: Registers,  Prev: Arithmetic,  Up: Top
+
+5 Stack Control
+***************
+
+`c'
+     Clears the stack, rendering it empty.
+
+`d'
+     Duplicates the value on the top of the stack, pushing another copy
+     of it.  Thus, `4d*p' computes 4 squared and prints it.
+
+`r'
+     Reverses the order of (swaps) the top two values on the stack.
+     (This can also be accomplished with the sequence `SaSbLaLb'.)
+     (This command is a GNU extension.)
+
+\1f
+File: dc.info,  Node: Registers,  Next: Parameters,  Prev: Stack Control,  Up: Top
+
+6 Registers
+***********
+
+`dc' provides at least 256 memory registers(1), each named by a single
+character.  You can store a number in a register and retrieve it later.
+
+`sR'
+     Pop the value off the top of the stack and store it into register
+     R.
+
+`lR'
+     Copy the value in register R, and push it onto the stack.  This
+     does not alter the contents of R.
+
+     Each register also contains its own stack.  The current register
+     value is the top of the register's stack.
+
+`SR'
+     Pop the value off the top of the (main) stack and push it onto the
+     stack of register R.  The previous value of the register becomes
+     inaccessible.
+
+`LR'
+     Pop the value off the top of register R's stack and push it onto
+     the main stack.  The previous value in register R's stack, if any,
+     is now accessible via the `lR' command.
+
+   ---------- Footnotes ----------
+
+   (1) The exact number of registers provided by `dc' depends on the
+range of an `unsigned char' in the C compiler used to create the `dc'
+executable.
+
+\1f
+File: dc.info,  Node: Parameters,  Next: Strings,  Prev: Registers,  Up: Top
+
+7 Parameters
+************
+
+`dc' has three parameters that control its operation: the precision,
+the input radix, and the output radix.  The precision specifies the
+number of fraction digits to keep in the result of most arithmetic
+operations.  The input radix controls the interpretation of numbers
+typed in; _all_ numbers typed in use this radix.  The output radix is
+used for printing numbers.
+
+   The input and output radices are separate parameters; you can make
+them unequal, which can be useful or confusing.  The input radix must
+be between 2 and 16 inclusive.  The output radix must be at least 2.
+The precision must be zero or greater.  The precision is always
+measured in decimal digits, regardless of the current input or output
+radix.
+
+`i'
+     Pops the value off the top of the stack and uses it to set the
+     input radix.
+
+`o'
+     Pops the value off the top of the stack and uses it to set the
+     output radix.
+
+`k'
+     Pops the value off the top of the stack and uses it to set the
+     precision.
+
+`I'
+     Pushes the current input radix on the stack.
+
+`O'
+     Pushes the current output radix on the stack.
+
+`K'
+     Pushes the current precision on the stack.
+
+
+\1f
+File: dc.info,  Node: Strings,  Next: Status Inquiry,  Prev: Parameters,  Up: Top
+
+8 Strings
+*********
+
+`dc' has a limited ability to operate on strings as well as on numbers;
+the only things you can do with strings are print them and execute them
+as macros (which means that the contents of the string are processed as
+`dc' commands).  Both registers and the stack can hold strings, and
+`dc' always knows whether any given object is a string or a number.
+Some commands such as arithmetic operations demand numbers as arguments
+and print errors if given strings.  Other commands can accept either a
+number or a string; for example, the `p' command can accept either and
+prints the object according to its type.
+
+`[CHARACTERS]'
+     Makes a string containing CHARACTERS and pushes it on the stack.
+     For example, `[foo]P' prints the characters `foo' (with no
+     newline).  Note that all square brackets (`['s and `]'s) must be
+     balanced; there is no mechanism provided for handling unbalanced
+     square brackets.
+
+`a'
+     The mnemonic for this is somewhat erroneous: asciify.  The
+     top-of-stack is popped.  If it was a number, then the low-order
+     byte of this number is converted into a 1-character string and
+     pushed onto the stack.  Otherwise the top-of-stack was a string,
+     and the first character of that string is pushed back.  (This
+     command is a GNU extension.)
+
+`x'
+     Pops a value off the stack and executes it as a macro.  Normally
+     it should be a string; if it is a number, it is simply pushed back
+     onto the stack.  For example, `[1p]x' executes the macro `1p',
+     which pushes 1 on the stack and prints `1' on a separate line.
+
+     Macros are most often stored in registers; `[1p]sa' stores a macro
+     to print `1' into register `a', and `lax' invokes the macro.
+
+`>R'
+     Pops two values off the stack and compares them assuming they are
+     numbers, executing the contents of register R as a macro if the
+     original top-of-stack is greater.  Thus, `1 2>a' will invoke
+     register `a''s contents and `2 1>a' will not.
+
+`!>R'
+     Similar but invokes the macro if the original top-of-stack is not
+     greater (is less than or equal to) what was the second-to-top.
+
+`<R'
+     Similar but invokes the macro if the original top-of-stack is less.
+
+`!<R'
+     Similar but invokes the macro if the original top-of-stack is not
+     less (is greater than or equal to) what was the second-to-top.
+
+`=R'
+     Similar but invokes the macro if the two numbers popped are equal.
+
+`!=R'
+     Similar but invokes the macro if the two numbers popped are not
+     equal.
+
+`?'
+     Reads a line from the terminal and executes it.  This command
+     allows a macro to request input from the user.
+
+`q'
+     During the execution of a macro, this command exits from the macro
+     and also from the macro which invoked it.  If called from the top
+     level, or from a macro which was called directly from the top
+     level, the `q' command will cause `dc' to exit.
+
+`Q'
+     Pops a value off the stack and uses it as a count of levels of
+     macro execution to be exited.  Thus, `3Q' exits three levels.
+
+\1f
+File: dc.info,  Node: Status Inquiry,  Next: Miscellaneous,  Prev: Strings,  Up: Top
+
+9 Status Inquiry
+****************
+
+`Z'
+     Pops a value off the stack, calculates the number of digits it has
+     (or number of characters, if it is a string) and pushes that
+     number.
+
+     Note that the digit count for a number does _not_ include any
+     leading zeros, even if those appear to the right of the radix
+     point.  This may seem a bit strange at first, but it is compatable
+     with historical implementations of `dc', and can be argued to be
+     useful for computing the magnitude of a value: `dSaXLaZ-' will
+     compute the power-of-ten multiplier which would be needed to shift
+     the decimal point to be immediately before the leftmost non-zero
+     digit.
+
+`X'
+     Pops a value off the stack, calculates the number of fraction
+     digits it has, and pushes that number.  For a string, the value
+     pushed is 0.
+
+`z'
+     Pushes the current stack depth: the number of objects on the stack
+     before the execution of the `z' command.
+
+\1f
+File: dc.info,  Node: Miscellaneous,  Next: Reporting bugs,  Prev: Status Inquiry,  Up: Top
+
+10 Miscellaneous
+****************
+
+`!'
+     Will run the rest of the line as a system command.  Note that
+     parsing of the !<, !=, and !> commands take precidence, so if you
+     want to run a command starting with <, =, or > you will need to
+     add a space after the !.
+
+`#'
+     Will interpret the rest of the line as a comment.  (This command
+     is a GNU extension.)
+
+`:R'
+     Will pop the top two values off of the stack.  The old
+     second-to-top value will be stored in the array R, indexed by the
+     old top-of-stack value.
+
+`;R'
+     Pops the top-of-stack and uses it as an index into the array R.
+     The selected value is then pushed onto the stack.
+
+   Note that each stacked instance of a register has its own array
+associated with it.  Thus `1 0:A 0SA 2 0:A LA 0;Ap' will print 1,
+because the 2 was stored in an instance of 0:A that was later popped.
+
+\1f
+File: dc.info,  Node: Reporting bugs,  Prev: Miscellaneous,  Up: Top
+
+11 Reporting bugs
+*****************
+
+Email bug reports to <bug-dc@gnu.org>.  
+
+
+\1f
+Tag Table:
+Node: Top\7f1109
+Node: Introduction\7f1688
+Node: Invocation\7f3037
+Node: Printing Commands\7f3888
+Node: Arithmetic\7f5933
+Node: Stack Control\7f8850
+Node: Registers\7f9334
+Ref: Registers-Footnote-1\7f10302
+Node: Parameters\7f10454
+Node: Strings\7f11719
+Node: Status Inquiry\7f14876
+Node: Miscellaneous\7f15936
+Node: Reporting bugs\7f16909
+\1f
+End Tag Table
diff --git a/doc/dc.texi b/doc/dc.texi
new file mode 100644 (file)
index 0000000..93fb740
--- /dev/null
@@ -0,0 +1,574 @@
+\input texinfo  @c -*-texinfo-*-
+@c %**start of header
+@setfilename dc.info
+@settitle dc, an arbitrary precision calculator
+@c %**end of header
+
+@include texi-ver.incl
+
+@c This file has the new style title page commands.
+@c Run `makeinfo' rather than `texinfo-format-buffer'.
+
+@c smallbook
+
+@c tex
+@c \overfullrule=0pt
+@c end tex
+
+@c Combine indices.
+@synindex cp fn
+@syncodeindex vr fn
+@syncodeindex ky fn
+@syncodeindex pg fn
+@syncodeindex tp fn
+
+@ifinfo
+@direntry
+* dc: (dc).                   Arbitrary precision RPN ``Desktop Calculator''.
+@end direntry
+
+This file documents @command{dc}, an arbitrary precision calculator.
+
+Published by the Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor
+Boston, MA 02110-1301  USA
+
+Copyright (C) 1984, 1994, 1997, 1998, 2000, 2005, 2006 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end ifinfo
+
+@setchapternewpage off
+
+@titlepage
+@title dc, an arbitrary precision calculator
+@subtitle version @value{DC_VERSION}
+
+@author by Ken Pizzini
+@author original manual by Richard Stallman
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1984, 1994, 1997, 1998, 2000, 2005, 2006
+Free Software Foundation, Inc.
+
+@sp 2
+Published by the Free Software Foundation, @*
+51 Franklin Street, Fifth Floor @*
+Boston, MA 02110-1301  USA
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+
+@end titlepage
+
+@node Top, Introduction, (dir), (dir)
+
+@menu
+* Introduction::                Introduction
+* Invocation::                  Invocation
+* Printing Commands::           Printing Commands
+* Arithmetic::                  Arithmetic
+* Stack Control::               Stack Control
+* Registers::                   Registers
+* Parameters::                  Parameters
+* Strings::                     Strings
+* Status Inquiry::              Status Inquiry
+* Miscellaneous::               Other commands
+* Reporting bugs::              Reporting bugs
+@end menu
+
+@node Introduction, Invocation, Top, Top
+@comment  node-name,  next,  previous,  up
+@chapter Introduction
+
+@command{dc} is a reverse-polish desk calculator
+which supports unlimited precision arithmetic.
+It also allows you to define and call macros.
+Normally @command{dc} reads from the standard input;
+if any command arguments are given to it, they are filenames,
+and @command{dc} reads and executes the contents of the files
+instead of reading from standard input.
+All normal output is to standard output;
+all error messages are written to standard error.
+
+To exit, use @samp{q}.
+@kbd{C-c}
+(or whatever other keystroke your system uses to generate a @code{SIGINT})
+does not exit;
+it is used to abort macros that are looping, etc.
+
+A reverse-polish calculator stores numbers on a stack.
+Entering a number pushes it on the stack.
+Arithmetic operations pop arguments off the stack and push the results.
+
+To enter a number in @command{dc}, type the digits (using upper
+case letters @code{A} through @code{F} as "digits" when working
+with input bases greater than ten),
+with an optional decimal point.
+Exponential notation is not supported.
+To enter a negative number, begin the number with @samp{_}.
+@samp{-} cannot be used for this, as it is a binary operator
+for subtraction instead.
+To enter two numbers in succession,
+separate them with spaces or newlines;
+these have no meaning as commands.
+
+@node Invocation, Printing Commands, Introduction, Top
+@chapter Invocation
+
+@command{dc} may be invoked with the following command-line options:
+@table @samp
+
+@item -e @var{expr}
+@item --expression=@var{expr}
+Evaluate @var{expr} as @command{dc} commands.
+
+@item -f @var{file}
+@item --file=@var{file}
+Read and evaluate @command{dc} commands from @var{file}.
+
+@item -h
+@item --help
+Print a usage message summarizing the command-line options, then exit.
+
+@item -V
+@item --version
+Print the version information for this program, then exit.
+@end table
+
+If any command-line parameters remain after processing the options,
+these parameters are interpreted as additional @var{file}s whose
+contents are read and evaluated.
+A file name of @code{-} refers to the standard input stream.
+If no @code{-e} option was specified, and no files were specified,
+then the standard input will be read for commands to evaluate.
+
+@node Printing Commands, Arithmetic, Invocation, Top
+@chapter Printing Commands
+
+@table @samp
+@item p
+Prints the value on the top of the stack,
+without altering the stack.
+A newline is printed after the value.
+
+@item n
+Prints the value on the top of the stack, popping it off,
+and does not print a newline after.
+(This command is a GNU extension.)
+
+@item P
+Pops off the value on top of the stack.
+If it it a string, it is simply printed without a trailing newline.
+Otherwise it is a number, and the integer portion of its absolute
+value is printed out as a "base (UCHAR_MAX+1)" byte stream.
+Assuming that (UCHAR_MAX+1) is 256
+(as it is on most machines with 8-bit bytes),
+the sequence
+@code{KSK0k1/ _1Ss[ls*]Sxd0>x
+[256~Ssd0<x]dsxx
+sx[q]Sq[Lsd0>qaPlxx]dsxx
+sx0sqLqsxLxLK+k}
+could also accomplish this function.
+(Much of the complexity of the above native-dc code is due
+to the ~ computing the characters backwards,
+and the desire to ensure that all registers wind up back
+in their original states.)
+(Details of the behavior with a number are a GNU extension.
+Traditional @command{dc} happened to "support" similar functionality
+for a limited range of inputs as an accidental side-effect of its
+internal representation of numbers.)
+
+@item f
+Prints the entire contents of the stack
+@c and the contents of all of the registers,
+without altering anything.
+This is a good command to use if you are lost or want
+to figure out what the effect of some command has been.
+@end table
+
+All numeric output is split to fit within 70 columns, by default.
+When a number is broken up in this way, the split is indicated
+by a "\" at the end of the to-be-continued output lines.
+The column width at which output is split can be overridden
+by setting the @var{DC_LINE_LENGTH} environment variable to
+the desired width.
+A @var{DC_LINE_LENGTH} of 0 (zero) disables the line-split
+feature altogether.
+Invalid values of @var{DC_LINE_LENGTH} are silently ignored.
+(The @var{DC_LINE_LENGTH} variable is a GNU extension.)
+
+@node Arithmetic, Stack Control, Printing Commands, Top
+@chapter Arithmetic
+
+@table @samp
+@item +
+Pops two values off the stack, adds them, and pushes the result.
+The precision of the result is determined only
+by the values of the arguments, and is enough to be exact.
+
+@item -
+Pops two values, subtracts the first one popped
+from the second one popped, and pushes the result.
+
+@item *
+Pops two values, multiplies them, and pushes the result.
+The number of fraction digits in the result is the largest of
+the precision value,
+the number of fraction digits in the multiplier,
+or the number of fraction digits in the multiplicand;
+but in no event exceeding the number of digits required for
+an exact result.
+
+@item /
+Pops two values, divides the second one popped
+from the first one popped, and pushes the result.
+The number of fraction digits is specified by the precision value.
+
+@item %
+Pops two values,
+computes the remainder of the division that
+the @samp{/} command would do,
+and pushes that.
+The value computed is the same as that computed by
+the sequence @code{Sd dld/ Ld*-} .
+
+@item ~
+Pops two values,
+divides the second one popped from the first one popped.
+The quotient is pushed first, and the remainder is pushed next.
+The number of fraction digits used in the division
+is specified by the precision value.
+(The sequence @code{SdSn lnld/ LnLd%} could also accomplish
+this function, with slightly different error checking.)
+(This command is a GNU extension.)
+
+@item ^
+Pops two values and exponentiates,
+using the first value popped as the exponent
+and the second popped as the base.
+The fraction part of the exponent is ignored.
+The precision value specifies the number of fraction
+digits in the result.
+
+@item |
+Pops three values and computes a modular exponentiation.
+The first value popped is used as the reduction modulus;
+this value must be a non-zero number,
+and the result may not be accurate if the modulus
+is not an integer.
+The second popped is used as the exponent;
+this value must be a non-negative number,
+and any fractional part of this exponent will be ignored.
+The third value popped is the base which gets exponentiated,
+which should be an integer.
+For small integers this is like the sequence @code{Sm^Lm%},
+but, unlike @code{^},
+this command will work with arbritrarily large exponents.
+(This command is a GNU extension.)
+
+@item v
+Pops one value, computes its square root, and pushes that.
+The precision value specifies the number of fraction digits
+in the result.
+@end table
+
+Most arithmetic operations are affected by the @emph{precision value},
+which you can set with the @samp{k} command.
+The default precision value is zero,
+which means that all arithmetic except for
+addition and subtraction produces integer results.
+
+@node Stack Control, Registers, Arithmetic, Top
+@chapter Stack Control
+
+@table @samp
+@item c
+Clears the stack, rendering it empty.
+
+@item d
+Duplicates the value on the top of the stack,
+pushing another copy of it.
+Thus, @samp{4d*p} computes 4 squared and prints it.
+
+@item r
+Reverses the order of (swaps) the top two values on the stack.
+(This can also be accomplished with the sequence @code{SaSbLaLb}.)
+(This command is a GNU extension.)
+@end table
+
+@node Registers, Parameters, Stack Control, Top
+@chapter Registers
+
+@command{dc} provides at least 256 memory registers@footnote{The
+exact number of registers provided by @command{dc} depends
+on the range of an @code{unsigned char} in the C compiler
+used to create the @command{dc} executable.},
+each named by a single character.
+You can store a number in a register and retrieve it later.
+
+@table @samp
+@item s@var{r}
+Pop the value off the top of the stack and
+store it into register @var{r}.
+
+@item l@var{r}
+Copy the value in register @var{r},
+and push it onto the stack.
+This does not alter the contents of @var{r}.
+
+Each register also contains its own stack.
+The current register value is the top of the register's stack.
+
+@item S@var{r}
+Pop the value off the top of the (main) stack and
+push it onto the stack of register @var{r}.
+The previous value of the register becomes inaccessible.
+
+@item L@var{r}
+Pop the value off the top of register @var{r}'s stack
+and push it onto the main stack.
+The previous value in register @var{r}'s stack, if any,
+is now accessible via the @samp{l@var{r}} command.
+@end table
+@c 
+@c The @samp{f} command prints a list of all registers that have contents
+@c stored in them, together with their contents.
+@c Only the current contents of each register (the top of its stack)
+@c is printed.
+
+@node Parameters, Strings, Registers, Top
+@chapter Parameters
+
+@command{dc} has three parameters that control its operation:
+the precision, the input radix, and the output radix.
+The precision specifies the number of fraction digits
+to keep in the result of most arithmetic operations.
+The input radix controls the interpretation of numbers typed in;
+@emph{all} numbers typed in use this radix.
+The output radix is used for printing numbers.
+
+The input and output radices are separate parameters;
+you can make them unequal, which can be useful or confusing.
+The input radix must be between 2 and 16 inclusive.
+The output radix must be at least 2.
+The precision must be zero or greater.
+The precision is always measured in decimal digits,
+regardless of the current input or output radix.
+
+@table @samp
+@item i
+Pops the value off the top of the stack
+and uses it to set the input radix.
+
+@item o
+Pops the value off the top of the stack
+and uses it to set the output radix.
+
+@item k
+Pops the value off the top of the stack
+and uses it to set the precision.
+
+@item I
+Pushes the current input radix on the stack.
+
+@item O
+Pushes the current output radix on the stack.
+
+@item K
+Pushes the current precision on the stack.
+
+@end table
+
+@node Strings, Status Inquiry, Parameters, Top
+@chapter Strings
+
+@command{dc} has a limited ability
+to operate on strings as well as on numbers;
+the only things you can do with strings are print them
+and execute them as macros
+(which means that the contents of the string are processed
+as @command{dc} commands).
+Both registers and the stack can hold strings,
+and @command{dc} always knows whether any given object is
+a string or a number.
+Some commands such as arithmetic operations demand numbers
+as arguments and print errors if given strings.
+Other commands can accept either a number or a string;
+for example, the @samp{p} command can accept either and prints the object
+according to its type.
+
+@table @samp
+@item [@var{characters}]
+Makes a string containing @var{characters} and pushes it on the stack.
+For example, @samp{[foo]P} prints the characters @samp{foo}
+(with no newline).
+Note that all square brackets (@samp{[}s and @samp{]}s) must be balanced;
+there is no mechanism provided for handling unbalanced square brackets.
+
+@item a
+The mnemonic for this is somewhat erroneous: asciify.
+The top-of-stack is popped.
+If it was a number, then the low-order byte of this number
+is converted into a 1-character string
+and pushed onto the stack.
+Otherwise the top-of-stack was a string,
+and the first character of that string is pushed back.
+(This command is a GNU extension.)
+
+@item x
+Pops a value off the stack and executes it as a macro.
+Normally it should be a string;
+if it is a number, it is simply pushed back onto the stack.
+For example, @samp{[1p]x} executes the macro @samp{1p},
+which pushes 1 on the stack and prints @samp{1} on a separate line.
+
+Macros are most often stored in registers;
+@samp{[1p]sa} stores a macro to print @samp{1} into register @samp{a},
+and @samp{lax} invokes the macro.
+
+@item >@var{r}
+Pops two values off the stack and compares them
+assuming they are numbers,
+executing the contents of register @var{r} as a macro
+if the original top-of-stack is greater.
+Thus, @samp{1 2>a} will invoke register @samp{a}'s contents
+and @samp{2 1>a} will not.
+
+@item !>@var{r}
+Similar but invokes the macro if the original top-of-stack is not greater
+(is less than or equal to) what was the second-to-top.
+
+@item <@var{r}
+Similar but invokes the macro if the original top-of-stack is less.
+
+@item !<@var{r}
+Similar but invokes the macro if the original top-of-stack is not less
+(is greater than or equal to) what was the second-to-top.
+
+@item =@var{r}
+Similar but invokes the macro if the two numbers popped are equal.
+@c This can also be validly used to compare two strings for equality.
+
+@item !=@var{r}
+Similar but invokes the macro if the two numbers popped are not equal.
+@c This can also be validly used to compare two strings for equality.
+
+@item ?
+Reads a line from the terminal and executes it.
+This command allows a macro to request input from the user.
+
+@item q
+During the execution of a macro,
+this command exits from the macro and also from the macro which invoked it.
+If called from the top level,
+or from a macro which was called directly from the top level,
+the @samp{q} command will cause @command{dc} to exit.
+
+@item Q
+Pops a value off the stack and uses it as a count
+of levels of macro execution to be exited.
+Thus, @samp{3Q} exits three levels.
+@end table
+
+@node Status Inquiry, Miscellaneous, Strings, Top
+@chapter Status Inquiry
+
+@table @samp
+@item Z
+Pops a value off the stack,
+calculates the number of digits it has
+(or number of characters, if it is a string)
+and pushes that number.
+
+Note that the digit count for a number does
+@emph{not} include any leading zeros,
+even if those appear to the right of the radix point.
+This may seem a bit strange at first,
+but it is compatable with historical implementations of @command{dc},
+and can be argued to be useful for computing the magnitude of a value:
+@code{dSaXLaZ-} will compute the power-of-ten multiplier
+which would be needed to shift the decimal point
+to be immediately before the leftmost non-zero digit.
+
+@item X
+Pops a value off the stack,
+calculates the number of fraction digits it has,
+and pushes that number.
+For a string, the value pushed is
+@c -1.
+0.
+
+@item z
+Pushes the current stack depth:
+the number of objects on the stack
+before the execution of the @samp{z} command.
+@end table
+
+@node Miscellaneous, Reporting bugs, Status Inquiry, Top
+@chapter Miscellaneous
+
+@table @samp
+@item !
+Will run the rest of the line as a system command.
+Note that parsing of the !<, !=, and !> commands take precidence,
+so if you want to run a command starting with <, =, or > you will
+need to add a space after the !.
+
+@item #
+Will interpret the rest of the line as a comment.
+(This command is a GNU extension.)
+
+@item :@var{r}
+Will pop the top two values off of the stack.
+The old second-to-top value will be stored in the array @var{r},
+indexed by the old top-of-stack value.
+
+@item ;@var{r}
+Pops the top-of-stack and uses it as an index into
+the array @var{r}.
+The selected value is then pushed onto the stack.
+@end table
+
+Note that each stacked instance of a register has its own
+array associated with it.
+Thus @samp{1 @var{0:a} 0S@var{a} 2 @var{0:a} L@var{a} @var{0;a}p}
+will print 1, because the 2 was stored in an instance of @var{0:a}
+that was later popped.
+
+@node Reporting bugs,  , Miscellaneous, Top
+@chapter Reporting bugs
+
+Email bug reports to @email{bug-dc@@gnu.org}.
+@contents
+@bye
diff --git a/doc/texi-ver.incl.in b/doc/texi-ver.incl.in
new file mode 100644 (file)
index 0000000..6373f4f
--- /dev/null
@@ -0,0 +1,2 @@
+@set BC_VERSION @BC_VERSION@
+@set DC_VERSION @DC_VERSION@
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
new file mode 100644 (file)
index 0000000..ff2c406
--- /dev/null
@@ -0,0 +1,7210 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2005-07-05.19}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
+% Foundation, Inc.
+%
+% This texinfo.tex file is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation; either version 2, or (at
+% your option) any later version.
+%
+% This texinfo.tex file is distributed in the hope that it will be
+% useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+% of MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 texinfo.tex file; see the file COPYING.  If not, write
+% to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+% Boston, MA 02110-1301, USA.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction.  (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+%   http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+%   ftp://tug.org/tex/texinfo.tex
+%     (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org.  Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem.  Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution.  For a simple
+% manual foo.texi, however, you can get away with this:
+%   tex foo.texi
+%   texindex foo.??
+%   tex foo.texi
+%   tex foo.texi
+%   dvips foo.dvi -o  # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent.  You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+  \catcode`+=\active \catcode`\_=\active}
+
+\message{Basics,}
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+  \let\linenumber = \empty % Pre-3.0.
+\else
+  \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined  \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined   \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined      \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined        \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined     \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined      \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined  \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined   \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined        \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined        \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined      \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined   \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined   \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined       \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined       \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined  \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined       \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined    \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined   \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined    \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined    \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined   \gdef\putwordDeffunc{Function}\fi
+
+% In some macros, we cannot use the `\? notation---the left quote is
+% in some cases the escape char.
+\chardef\backChar  = `\\
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dotChar   = `\.
+\chardef\exclamChar= `\!
+\chardef\plusChar  = `\+
+\chardef\questChar = `\?
+\chardef\semiChar  = `\;
+\chardef\underChar = `\_
+
+\chardef\spaceChar = `\ %
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode\spaceChar=\spacecat}
+
+{% for help with debugging.
+ % example usage: \expandafter\show\activebackslash
+ \catcode`\! = 0 \catcode`\\ = \active
+ !global!def!activebackslash{\}
+}
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+  Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+  ap-pen-dix bit-map bit-maps
+  data-base data-bases eshell fall-ing half-way long-est man-u-script
+  man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+  par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+  spell-ing spell-ings
+  stand-alone strong-est time-stamp time-stamps which-ever white-space
+  wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line.  It should
+% surround any changed text.  This approach does *not* work if the
+% change spans more than two lines of output.  To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+  % \vadjust can only be used in horizontal mode.
+  \leavevmode
+  %
+  % Append this vertical mode material after the current line in the output.
+  \vadjust{%
+    % We want to insert a rule with the height and depth of the current
+    % leading; that is exactly what \strutbox is supposed to record.
+    \vskip-\baselineskip
+    %
+    % \vadjust-items are inserted at the left edge of the type.  So
+    % the \llap here moves out into the left-hand margin.
+    \llap{%
+      %
+      % For a thicker or thinner bar, change the `1pt'.
+      \vrule height\baselineskip width1pt
+      %
+      % This is the space between the bar and the text.
+      \hskip 12pt
+    }%
+  }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal.  We don't just call \tracingall here,
+% since that produces some useless output on the terminal.  We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+  \tracingstats2
+  \tracingpages1
+  \tracinglostchars2  % 2 gives us more in etex
+  \tracingparagraphs1
+  \tracingoutput1
+  \tracingmacros2
+  \tracingrestores1
+  \showboxbreadth\maxdimen \showboxdepth\maxdimen
+  \ifx\eTeXversion\undefined\else % etex gives us more logging
+    \tracingscantokens1
+    \tracingifs1
+    \tracinggroups1
+    \tracingnesting2
+    \tracingassigns1
+  \fi
+  \tracingcommands3  % 3 gives us more in etex
+  \errorcontextlines16
+}%
+
+% add check for \lastpenalty to plain's definitions.  If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+  \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+  \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+  \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong  \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument.  Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+  \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+  %
+  \ifodd\pageno  \advance\hoffset by \bindingoffset
+  \else \advance\hoffset by -\bindingoffset\fi
+  %
+  % Do this outside of the \shipout so @code etc. will be expanded in
+  % the headline as they should be, not taken literally (outputting ''code).
+  \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+  \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+  %
+  {%
+    % Have to do this stuff outside the \shipout because we want it to
+    % take effect in \write's, yet the group defined by the \vbox ends
+    % before the \shipout runs.
+    %
+    \indexdummies         % don't expand commands in the output.
+    \shipout\vbox{%
+      % Do this early so pdf references go to the beginning of the page.
+      \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+      %
+      \ifcropmarks \vbox to \outervsize\bgroup
+        \hsize = \outerhsize
+        \vskip-\topandbottommargin
+        \vtop to0pt{%
+          \line{\ewtop\hfil\ewtop}%
+          \nointerlineskip
+          \line{%
+            \vbox{\moveleft\cornerthick\nstop}%
+            \hfill
+            \vbox{\moveright\cornerthick\nstop}%
+          }%
+          \vss}%
+        \vskip\topandbottommargin
+        \line\bgroup
+          \hfil % center the page within the outer (page) hsize.
+          \ifodd\pageno\hskip\bindingoffset\fi
+          \vbox\bgroup
+      \fi
+      %
+      \unvbox\headlinebox
+      \pagebody{#1}%
+      \ifdim\ht\footlinebox > 0pt
+        % Only leave this space if the footline is nonempty.
+        % (We lessened \vsize for it in \oddfootingxxx.)
+        % The \baselineskip=24pt in plain's \makefootline has no effect.
+        \vskip 2\baselineskip
+        \unvbox\footlinebox
+      \fi
+      %
+      \ifcropmarks
+          \egroup % end of \vbox\bgroup
+        \hfil\egroup % end of (centering) \line\bgroup
+        \vskip\topandbottommargin plus1fill minus1fill
+        \boxmaxdepth = \cornerthick
+        \vbox to0pt{\vss
+          \line{%
+            \vbox{\moveleft\cornerthick\nsbot}%
+            \hfill
+            \vbox{\moveright\cornerthick\nsbot}%
+          }%
+          \nointerlineskip
+          \line{\ewbot\hfil\ewbot}%
+        }%
+      \egroup % \vbox from first cropmarks clause
+      \fi
+    }% end of \shipout\vbox
+  }% end of group with \indexdummies
+  \advancepageno
+  \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+  \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks.  Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1.  The argument is the rest of
+% the input line (except we remove a trailing comment).  #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+  \def\next{#2}%
+  \begingroup
+    \obeylines
+    \spaceisspace
+    #1%
+    \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+  \gdef\parseargline#1^^M{%
+    \endgroup % End of the group started in \parsearg.
+    \argremovecomment #1\comment\ArgTerm%
+  }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+%    @end itemize  @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+  \def\temp{#3}%
+  \ifx\temp\empty
+    % We cannot use \next here, as it holds the macro to run;
+    % thus we reuse \temp.
+    \let\temp\finishparsearg
+  \else
+    \let\temp\argcheckspaces
+  \fi
+  % Put the space token in:
+  \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \next.
+% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
+
+% \parseargdef\foo{...}
+%      is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick.  --kasal, 16nov03
+
+\def\parseargdef#1{%
+  \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+  \def#2{\parsearg#1}%
+  \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+  \obeyspaces
+  \gdef\obeyedspace{ }
+
+  % Make each space character in the input produce a normal interword
+  % space in the output.  Don't allow a line break at this space, as this
+  % is used only in environments like @example, where each line of input
+  % should produce a line of output anyway.
+  %
+  \gdef\sepspaces{\obeyspaces\let =\tie}
+
+  % If an index command is used in an @example environment, any spaces
+  % therein should become regular spaces in the raw index file, not the
+  % expansion of \tie (\leavevmode \penalty \@M \ ).
+  \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex.  It's used like this:
+%
+%   \envdef\foo{...}
+%   \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo.  \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches.  The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as enviroments; they don't open a group.  (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At runtime, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+  \def\temp{#1}%
+  \ifx\thisenv\temp
+  \else
+    \badenverr
+  \fi
+}
+
+% Evironment mismatch, #1 expected:
+\def\badenverr{%
+  \errhelp = \EMsimple
+  \errmessage{This command can appear only \inenvironment\temp,
+    not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+  \ifx#1\empty
+    out of any environment%
+  \else
+    in environment \expandafter\string#1%
+  \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+  \if 1\csname iscond.#1\endcsname
+  \else
+    % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+    \expandafter\checkenv\csname#1\endcsname
+    \csname E#1\endcsname
+    \endgroup
+  \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+  % Definitions to produce \{ and \} commands for indices,
+  % and @{ and @} for the aux/toc files.
+  \catcode`\{ = \other \catcode`\} = \other
+  \catcode`\[ = 1 \catcode`\] = 2
+  \catcode`\! = 0 \catcode`\\ = \other
+  !gdef!lbracecmd[\{]%
+  !gdef!rbracecmd[\}]%
+  !gdef!lbraceatcmd[@{]%
+  !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+  \def\temp{#1}%
+  \ifx\temp\imacro \ptexi
+  \else\ifx\temp\jmacro \j
+  \else \errmessage{@dotless can be used only with i or j}%
+  \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence.  (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo.  Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+  L\kern-.36em
+  {\setbox0=\hbox{T}%
+   \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+  \kern-.15em
+  \TeX
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off  says whether to put extra space after punctuation.
+% 
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+  \def\temp{#1}%
+  \ifx\temp\onword \plainfrenchspacing
+  \else\ifx\temp\offword \plainnonfrenchspacing
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+  \fi\fi
+}
+
+% @w prevents a word break.  Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line.  According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0).  If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large.  This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material.  In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom.  The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+  \ifnum\catcode`\^^M=\active \else
+    \errhelp = \groupinvalidhelp
+    \errmessage{@group invalid in context where filling is enabled}%
+  \fi
+  \startsavinginserts
+  %
+  \setbox\groupbox = \vtop\bgroup
+    % Do @comment since we are called inside an environment such as
+    % @example, where each end-of-line in the input causes an
+    % end-of-line in the output.  We don't want the end-of-line after
+    % the `@group' to put extra space in the output.  Since @group
+    % should appear on a line by itself (according to the Texinfo
+    % manual), we don't worry about eating any user text.
+    \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it.  Thus, space below is not quite equal to space
+% above.  But it's pretty close.
+\def\Egroup{%
+    % To get correct interline space between the last line of the group
+    % and the first line afterwards, we have to propagate \prevdepth.
+    \endgraf % Not \par, as it may have been set to \lisppar.
+    \global\dimen1 = \prevdepth
+  \egroup           % End the \vtop.
+  % \dimen0 is the vertical size of the group's box.
+  \dimen0 = \ht\groupbox  \advance\dimen0 by \dp\groupbox
+  % \dimen2 is how much space is left on the page (more or less).
+  \dimen2 = \pageheight   \advance\dimen2 by -\pagetotal
+  % if the group doesn't fit on the current page, and it's a big big
+  % group, force a page break.
+  \ifdim \dimen0 > \dimen2
+    \ifdim \pagetotal < \vfilllimit\pageheight
+      \page
+    \fi
+  \fi
+  \box\groupbox
+  \prevdepth = \dimen1
+  \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil  \mil=0.001in
+
+% Old definition--didn't work.
+%\parseargdef\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\parseargdef\need{%
+  % Ensure vertical mode, so we don't make a big box in the middle of a
+  % paragraph.
+  \par
+  %
+  % If the @need value is less than one line space, it's useless.
+  \dimen0 = #1\mil
+  \dimen2 = \ht\strutbox
+  \advance\dimen2 by \dp\strutbox
+  \ifdim\dimen0 > \dimen2
+    %
+    % Do a \strut just to make the height of this box be normal, so the
+    % normal leading is inserted relative to the preceding line.
+    % And a page break here is fine.
+    \vtop to #1\mil{\strut\vfil}%
+    %
+    % TeX does not even consider page breaks if a penalty added to the
+    % main vertical list is 10000 or more.  But in order to see if the
+    % empty box we just added fits on the page, we must make it consider
+    % page breaks.  On the other hand, we don't want to actually break the
+    % page after the empty box.  So we use a penalty of 9999.
+    %
+    % There is an extremely small chance that TeX will actually break the
+    % page at this \penalty, if there are no other feasible breakpoints in
+    % sight.  (If the user is using lots of big @group commands, which
+    % almost-but-not-quite fill up a page, TeX will have a hard time doing
+    % good page breaking, for example.)  However, I could not construct an
+    % example where a page broke at this \penalty; if it happens in a real
+    % document, then we can reconsider our strategy.
+    \penalty9999
+    %
+    % Back up by the size of the box, whether we did a page break or not.
+    \kern -#1\mil
+    %
+    % Do not allow a page break right after this kern.
+    \nobreak
+  \fi
+}
+
+% @br   forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+  \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph.  For more general purposes, use the \margin insertion
+% class.  WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+  \nobreak
+  \kern-\strutdepth
+  \vtop to \strutdepth{%
+    \baselineskip=\strutdepth
+    \vss
+    % if you have multiple lines of stuff to put here, you'll need to
+    % make the vbox yourself of the appropriate size.
+    \ifx#1l%
+      \llap{\ignorespaces #2\hskip\inmarginspacing}%
+    \else
+      \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+    \fi
+    \null
+  }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+  \setbox0 = \hbox{\ignorespaces #2}%
+  \ifdim\wd0 > 0pt
+    \def\lefttext{#1}%  have both texts
+    \def\righttext{#2}%
+  \else
+    \def\lefttext{#1}%  have only one text
+    \def\righttext{#1}%
+  \fi
+  %
+  \ifodd\pageno
+    \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+  \else
+    \def\temp{\inleftmargin\lefttext}%
+  \fi
+  \temp
+}
+
+% @include file    insert text of that file as input.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+  \pushthisfilestack
+  \def\thisfile{#1}%
+  {%
+    \makevalueexpandable
+    \def\temp{\input #1 }%
+    \expandafter
+  }\temp
+  \popthisfilestack
+}
+\def\filenamecatcodes{%
+  \catcode`\\=\other
+  \catcode`~=\other
+  \catcode`^=\other
+  \catcode`_=\other
+  \catcode`|=\other
+  \catcode`<=\other
+  \catcode`>=\other
+  \catcode`+=\other
+  \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+  \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+  \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+  \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+  the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+  \ifhmode
+    \let\next\centerH
+  \else
+    \let\next\centerV
+  \fi
+  \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+  {%
+    \hfil\break
+    \advance\hsize by -\leftskip
+    \advance\hsize by -\rightskip
+    \line{#1}%
+    \break
+  }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n   outputs n lines of vertical space
+
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore  is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \defaultparindent = 0pt
+    \else
+      \defaultparindent = #1em
+    \fi
+  \fi
+  \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \lispnarrowing = 0pt
+    \else
+      \lispnarrowing = #1em
+    \fi
+  \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading.  If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\noneword
+    \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+  \else\ifx\temp\insertword
+    \let\suppressfirstparagraphindent = \relax
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @firstparagraphindent option `\temp'}%
+  \fi\fi
+}
+
+% Here is how we actually suppress indentation.  Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+  \gdef\indent{%
+    \restorefirstparagraphindent
+    \indent
+  }%
+  \gdef\noindent{%
+    \restorefirstparagraphindent
+    \noindent
+  }%
+  \global\everypar = {%
+    \kern -\parindent
+    \restorefirstparagraphindent
+  }%
+}
+
+\gdef\restorefirstparagraphindent{%
+  \global \let \indent = \ptexindent
+  \global \let \noindent = \ptexnoindent
+  \global \everypar = {}%
+}
+
+
+% @asis just yields its argument.  Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}.  So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+  \catcode\underChar = \active
+  \gdef\mathunderscore{%
+    \catcode\underChar=\active
+    \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+  }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care.  Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+  \tex
+  \mathunderscore
+  \let\\ = \mathbackslash
+  \mathactive
+  $\finishmath
+}
+\def\finishmath#1{#1$\endgroup}  % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+  \catcode`^ = \active
+  \catcode`< = \active
+  \catcode`> = \active
+  \catcode`+ = \active
+  \gdef\mathactive{%
+    \let^ = \ptexhat
+    \let< = \ptexless
+    \let> = \ptexgtr
+    \let+ = \ptexplus
+  }
+}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{$\ptexbullet$}
+\def\minus{$-$}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in a typewriter
+% font as three actual period characters.
+%
+\def\dots{%
+  \leavevmode
+  \hbox to 1.5em{%
+    \hskip 0pt plus 0.25fil
+    .\hfil.\hfil.%
+    \hskip 0pt plus 0.5fil
+  }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+  \dots
+  \spacefactor=\endofsentencespacefactor
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
+   \iflinks
+     \tryauxfile
+     % Open the new aux file.  TeX will close it automatically at exit.
+     \immediate\openout\auxfile=\jobname.aux
+   \fi % \openindices needs to do some work in any case.
+   \openindices
+   \let\setfilename=\comment % Ignore extra @setfilename cmds.
+   %
+   % If texinfo.cnf is present on the system, read it.
+   % Useful for site-wide @afourpaper, etc.
+   \openin 1 texinfo.cnf
+   \ifeof 1 \else \input texinfo.cnf \fi
+   \closein 1
+   %
+   \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+  \newindex{cp}%
+  \newcodeindex{fn}%
+  \newcodeindex{vr}%
+  \newcodeindex{tp}%
+  \newcodeindex{ky}%
+  \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set).  So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+  \ifx\pdfoutput\relax
+  \else
+    \ifcase\pdfoutput
+    \else
+      \pdftrue
+    \fi
+  \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets, to
+% for display in the outlines, and in other places.  Thus, we have to
+% double any backslashes.  Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e.  Not good.
+% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
+% (and related messages, the final outcome is that it is up to the TeX
+% user to double the backslashes and otherwise make the string valid, so
+% that's we do).
+
+% double active backslashes.
+% 
+{\catcode`\@=0 \catcode`\\=\active
+ @gdef@activebackslash{@catcode`@\=@active @otherbackslash}
+ @gdef@activebackslashdouble{%
+   @catcode@backChar=@active
+   @let\=@doublebackslash}
+}
+
+% To handle parens, we must adopt a different approach, since parens are
+% not active characters.  hyperref.dtx (which has the same problem as
+% us) handles it with this amazing macro to replace tokens.  I've
+% tinkered with it a little for texinfo, but it's definitely from there.
+% 
+% #1 is the tokens to replace.
+% #2 is the replacement.
+% #3 is the control sequence with the string.
+% 
+\def\HyPsdSubst#1#2#3{%
+  \def\HyPsdReplace##1#1##2\END{%
+    ##1%
+    \ifx\\##2\\%
+    \else
+      #2%
+      \HyReturnAfterFi{%
+        \HyPsdReplace##2\END
+      }%
+    \fi
+  }%
+  \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
+}
+\long\def\HyReturnAfterFi#1\fi{\fi#1}
+
+% #1 is a control sequence in which to do the replacements.
+\def\backslashparens#1{%
+  \xdef#1{#1}% redefine it as its expansion; the definition is simply
+             % \lastnode when called from \setref -> \pdfmkdest.
+  \HyPsdSubst{(}{\backslashlparen}{#1}%
+  \HyPsdSubst{)}{\backslashrparen}{#1}%
+}
+
+{\catcode\exclamChar = 0 \catcode\backChar = \other
+ !gdef!backslashlparen{\(}%
+ !gdef!backslashrparen{\)}%
+}
+
+\ifpdf
+  \input pdfcolor
+  \pdfcatalog{/PageMode /UseOutlines}%
+  \def\dopdfimage#1#2#3{%
+    \def\imagewidth{#2}%
+    \def\imageheight{#3}%
+    % without \immediate, pdftex seg faults when the same image is
+    % included twice.  (Version 3.14159-pre-1.0-unofficial-20010704.)
+    \ifnum\pdftexversion < 14
+      \immediate\pdfimage
+    \else
+      \immediate\pdfximage
+    \fi
+      \ifx\empty\imagewidth\else width \imagewidth \fi
+      \ifx\empty\imageheight\else height \imageheight \fi
+      \ifnum\pdftexversion<13
+         #1.pdf%
+       \else
+         {#1.pdf}%
+       \fi
+    \ifnum\pdftexversion < 14 \else
+      \pdfrefximage \pdflastximage
+    \fi}
+  \def\pdfmkdest#1{{%
+    % We have to set dummies so commands such as @code, and characters
+    % such as \, aren't expanded when present in a section title.
+    \atdummies
+    \activebackslashdouble
+    \def\pdfdestname{#1}%
+    \backslashparens\pdfdestname
+    \pdfdest name{\pdfdestname} xyz%
+  }}%
+  %
+  % used to mark target names; must be expandable.
+  \def\pdfmkpgn#1{#1}%
+  %
+  \let\linkcolor = \Blue  % was Cyan, but that seems light?
+  \def\endlink{\Black\pdfendlink}
+  % Adding outlines to PDF; macros for calculating structure of outlines
+  % come from Petr Olsak
+  \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+    \else \csname#1\endcsname \fi}
+  \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+    \advance\tempnum by 1
+    \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+  %
+  % #1 is the section text, which is what will be displayed in the
+  % outline by the pdf viewer.  #2 is the pdf expression for the number
+  % of subentries (or empty, for subsubsections).  #3 is the node text,
+  % which might be empty if this toc entry had no corresponding node.
+  % #4 is the page number
+  %
+  \def\dopdfoutline#1#2#3#4{%
+    % Generate a link to the node text if that exists; else, use the
+    % page number.  We could generate a destination for the section
+    % text in the case where a section has no node, but it doesn't
+    % seem worth the trouble, since most documents are normally structured.
+    \def\pdfoutlinedest{#3}%
+    \ifx\pdfoutlinedest\empty
+      \def\pdfoutlinedest{#4}%
+    \else
+      % Doubled backslashes in the name.
+      {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
+       \backslashparens\pdfoutlinedest}%
+    \fi
+    %
+    % Also double the backslashes in the display string.
+    {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
+     \backslashparens\pdfoutlinetext}%
+    %
+    \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+  }
+  %
+  \def\pdfmakeoutlines{%
+    \begingroup
+      % Thanh's hack / proper braces in bookmarks
+      \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+      \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+      %
+      % Read toc silently, to get counts of subentries for \pdfoutline.
+      \def\numchapentry##1##2##3##4{%
+       \def\thischapnum{##2}%
+       \def\thissecnum{0}%
+       \def\thissubsecnum{0}%
+      }%
+      \def\numsecentry##1##2##3##4{%
+       \advancenumber{chap\thischapnum}%
+       \def\thissecnum{##2}%
+       \def\thissubsecnum{0}%
+      }%
+      \def\numsubsecentry##1##2##3##4{%
+       \advancenumber{sec\thissecnum}%
+       \def\thissubsecnum{##2}%
+      }%
+      \def\numsubsubsecentry##1##2##3##4{%
+       \advancenumber{subsec\thissubsecnum}%
+      }%
+      \def\thischapnum{0}%
+      \def\thissecnum{0}%
+      \def\thissubsecnum{0}%
+      %
+      % use \def rather than \let here because we redefine \chapentry et
+      % al. a second time, below.
+      \def\appentry{\numchapentry}%
+      \def\appsecentry{\numsecentry}%
+      \def\appsubsecentry{\numsubsecentry}%
+      \def\appsubsubsecentry{\numsubsubsecentry}%
+      \def\unnchapentry{\numchapentry}%
+      \def\unnsecentry{\numsecentry}%
+      \def\unnsubsecentry{\numsubsecentry}%
+      \def\unnsubsubsecentry{\numsubsubsecentry}%
+      \readdatafile{toc}%
+      %
+      % Read toc second time, this time actually producing the outlines.
+      % The `-' means take the \expnumber as the absolute number of
+      % subentries, which we calculated on our first read of the .toc above.
+      %
+      % We use the node names as the destinations.
+      \def\numchapentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+      \def\numsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+      \def\numsubsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+      \def\numsubsubsecentry##1##2##3##4{% count is always zero
+        \dopdfoutline{##1}{}{##3}{##4}}%
+      %
+      % PDF outlines are displayed using system fonts, instead of
+      % document fonts.  Therefore we cannot use special characters,
+      % since the encoding is unknown.  For example, the eogonek from
+      % Latin 2 (0xea) gets translated to a | character.  Info from
+      % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+      %
+      % xx to do this right, we have to translate 8-bit characters to
+      % their "best" equivalent, based on the @documentencoding.  Right
+      % now, I guess we'll just let the pdf reader have its way.
+      \indexnofonts
+      \setupdatafile
+      \activebackslash
+      \input \jobname.toc
+    \endgroup
+  }
+  %
+  \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+    \ifx\PP\D\let\nextsp\relax
+    \else\let\nextsp\skipspaces
+      \ifx\p\space\else\addtokens{\filename}{\PP}%
+        \advance\filenamelength by 1
+      \fi
+    \fi
+    \nextsp}
+  \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+  \ifnum\pdftexversion < 14
+    \let \startlink \pdfannotlink
+  \else
+    \let \startlink \pdfstartlink
+  \fi
+  \def\pdfurl#1{%
+    \begingroup
+      \normalturnoffactive\def\@{@}%
+      \makevalueexpandable
+      \leavevmode\Red
+      \startlink attr{/Border [0 0 0]}%
+        user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+    \endgroup}
+  \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+  \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+  \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+  \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+  \def\maketoks{%
+    \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+    \ifx\first0\adn0
+    \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+    \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+    \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+    \else
+      \ifnum0=\countA\else\makelink\fi
+      \ifx\first.\let\next=\done\else
+        \let\next=\maketoks
+        \addtokens{\toksB}{\the\toksD}
+        \ifx\first,\addtokens{\toksB}{\space}\fi
+      \fi
+    \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+    \next}
+  \def\makelink{\addtokens{\toksB}%
+    {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+  \def\pdflink#1{%
+    \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+    \linkcolor #1\endlink}
+  \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+  \let\pdfmkdest = \gobble
+  \let\pdfurl = \gobble
+  \let\endlink = \relax
+  \let\linkcolor = \relax
+  \let\pdfmakeoutlines = \relax
+\fi  % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+  \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+  \csname ten#1\endcsname  % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+% Default leading.
+\newdimen\textleading  \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly.  There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+  \normalbaselineskip = #1\relax
+  \normallineskip = \lineskipfactor\normalbaselineskip
+  \normalbaselines
+  \setbox\strutbox =\hbox{%
+    \vrule width0pt height\strutheightpercent\baselineskip
+                    depth \strutdepthpercent \baselineskip
+  }%
+}
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor
+\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx}               %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}
+\setfont\deftt\ttshape{10}{\magstep1}
+\setfont\defttsl\ttslshape{10}{\magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}
+\setfont\smalltt\ttshape{9}{1000}
+\setfont\smallbf\bfshape{10}{900}
+\setfont\smallit\itshape{9}{1000}
+\setfont\smallsl\slshape{9}{1000}
+\setfont\smallsf\sfshape{9}{1000}
+\setfont\smallsc\scshape{10}{900}
+\setfont\smallttsl\ttslshape{10}{900}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}
+\setfont\smallertt\ttshape{8}{1000}
+\setfont\smallerbf\bfshape{10}{800}
+\setfont\smallerit\itshape{8}{1000}
+\setfont\smallersl\slshape{8}{1000}
+\setfont\smallersf\sfshape{8}{1000}
+\setfont\smallersc\scshape{10}{800}
+\setfont\smallerttsl\ttslshape{10}{800}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\setfont\titleit\itbshape{10}{\magstep4}
+\setfont\titlesl\slbshape{10}{\magstep4}
+\setfont\titlett\ttbshape{12}{\magstep3}
+\setfont\titlettsl\ttslshape{10}{\magstep4}
+\setfont\titlesf\sfbshape{17}{\magstep1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}
+\setfont\chapit\itbshape{10}{\magstep3}
+\setfont\chapsl\slbshape{10}{\magstep3}
+\setfont\chaptt\ttbshape{12}{\magstep2}
+\setfont\chapttsl\ttslshape{10}{\magstep3}
+\setfont\chapsf\sfbshape{17}{1000}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}
+\setfont\secit\itbshape{10}{\magstep2}
+\setfont\secsl\slbshape{10}{\magstep2}
+\setfont\sectt\ttbshape{12}{\magstep1}
+\setfont\secttsl\ttslshape{10}{\magstep2}
+\setfont\secsf\sfbshape{12}{\magstep1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{1315}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}
+\setfont\reducedtt\ttshape{10}{1000}
+\setfont\reducedbf\bfshape{10}{1000}
+\setfont\reducedit\itshape{10}{1000}
+\setfont\reducedsl\slshape{10}{1000}
+\setfont\reducedsf\sfshape{10}{1000}
+\setfont\reducedsc\scshape{10}{1000}
+\setfont\reducedttsl\ttslshape{10}{1000}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families.  Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+  \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+  \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+  \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE.  We do this because \STYLE needs to also set the
+% current \fam for math mode.  Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower).  These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+  \let\tenttsl=\textttsl
+  \def\curfontsize{text}%
+  \def\lsize{reduced}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+  \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+  \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+  \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+  \let\tenttsl=\titlettsl
+  \def\curfontsize{title}%
+  \def\lsize{chap}\def\lllsize{subsec}%
+  \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+  \let\tenttsl=\chapttsl
+  \def\curfontsize{chap}%
+  \def\lsize{sec}\def\lllsize{text}%
+  \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+  \let\tenttsl=\secttsl
+  \def\curfontsize{sec}%
+  \def\lsize{subsec}\def\lllsize{reduced}%
+  \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+  \let\tenttsl=\ssecttsl
+  \def\curfontsize{ssec}%
+  \def\lsize{text}\def\lllsize{small}%
+  \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+  \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+  \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+  \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+  \let\tenttsl=\reducedttsl
+  \def\curfontsize{reduced}%
+  \def\lsize{small}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+  \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+  \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+  \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+  \let\tenttsl=\smallttsl
+  \def\curfontsize{small}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+  \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+  \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+  \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+  \let\tenttsl=\smallerttsl
+  \def\curfontsize{smaller}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{9.5pt}}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts.  If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+%   8.5x11=86   smallbook=72  a4=90  a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+%   8.5x11=90+  smallbook=80  a4=90+  a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt.  So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+%   8.5x11=71  smallbook=60  a4=75  a5=58
+%
+% I wish the USA used A4 paper.
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts \rm
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}
+\setfont\shortcontbf\bfshape{10}{\magstep1}  % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}
+\setfont\shortconttt\ttshape{12}{1000}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+                    \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl.  We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% @b, explicit bold.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph.  Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+  \def\plainfrenchspacing{%
+    \sfcode\dotChar  =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+    \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+    \def\endofsentencespacefactor{1000}% for @. and friends
+  }
+  \def\plainnonfrenchspacing{%
+    \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+    \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+    \def\endofsentencespacefactor{3000}% for @. and friends
+  }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+\def\t#1{%
+  {\tt \rawbackslash \plainfrenchspacing #1}%
+  \null
+}
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\keyrm\rmshape{8}{1000}
+\font\keysy=cmsy9
+\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+    \vbox{\hrule\kern-0.4pt
+     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+    \kern-0.4pt\hrule}%
+  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+  {%
+    % Change normal interword space to be same as for the current font.
+    \spaceskip = \fontdimen2\font
+    %
+    % Switch to typewriter.
+    \tt
+    %
+    % But `\ ' produces the large typewriter interword space.
+    \def\ {{\spaceskip = 0pt{} }}%
+    %
+    % Turn off hyphenation.
+    \nohyphenation
+    %
+    \rawbackslash
+    \plainfrenchspacing
+    #1%
+  }%
+  \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+%  -- rms.
+{
+  \catcode`\-=\active
+  \catcode`\_=\active
+  %
+  \global\def\code{\begingroup
+    \catcode`\-=\active  \catcode`\_=\active
+    \ifallowcodebreaks
+     \let-\codedash
+     \let_\codeunder
+    \else
+     \let-\realdash
+     \let_\realunder
+    \fi
+    \codex
+  }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+  % this is all so @math{@code{var_name}+1} can work.  In math mode, _
+  % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+  % will therefore expand the active definition of _, which is us
+  % (inside @code that is), therefore an endless loop.
+  \ifusingtt{\ifmmode
+               \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+             \else\normalunderscore \fi
+             \discretionary{}{}{}}%
+            {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__.  This is undesirable in
+% some manuals, especially if they don't have long identifiers in
+% general.  @allowcodebreaks provides a way to control this.
+% 
+\newif\ifallowcodebreaks  \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\keywordtrue
+    \allowcodebreakstrue
+  \else\ifx\txiarg\keywordfalse
+    \allowcodebreaksfalse
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+  \fi\fi
+}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+%   `example' (@kbd uses ttsl only inside of @example and friends),
+%   or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+  \def\txiarg{#1}%
+  \ifx\txiarg\worddistinct
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+  \else\ifx\txiarg\wordexample
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+  \else\ifx\txiarg\wordcode
+    \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
+  \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct.'
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself.  First (mandatory) arg is the url.  Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+  \unsepspaces
+  \pdfurl{#1}%
+  \setbox0 = \hbox{\ignorespaces #3}%
+  \ifdim\wd0 > 0pt
+    \unhbox0 % third arg given, show only that
+  \else
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0 > 0pt
+      \ifpdf
+        \unhbox0             % PDF: 2nd arg given, show only it
+      \else
+        \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+      \fi
+    \else
+      \code{#1}% only url given, so show it
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+  \def\email#1{\doemail#1,,\finish}
+  \def\doemail#1,#2,#3\finish{\begingroup
+    \unsepspaces
+    \pdfurl{mailto:#1}%
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+    \endlink
+  \endgroup}
+\else
+  \let\email=\uref
+\fi
+
+% Check if we are currently using a typewriter font.  Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find.  We need it for
+% Polish suppressed-l.  --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}}              % roman font
+\def\sc#1{{\smallcaps#1}}       % smallcaps font
+\def\ii#1{{\it #1}}             % italic font
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+% 
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+  {\selectfonts\lsize #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+% 
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+  {\plainfrenchspacing #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+% 
+% Although only regular is the truly official Euro symbol, we ignore
+% that.  The Euro is designed to be slightly taller than the regular
+% font height.
+% 
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+% 
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+% 
+% Also doesn't work in math.  Do we need to do math with euro symbols?
+% Hope not.
+% 
+% 
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+  % We set the font at each command, rather than predefining it in
+  % \textfonts and the other font-switching commands, so that
+  % installations which never need the symbol don't have to have the
+  % font installed.
+  % 
+  % There is only one designed size (nominal 10pt), so we always scale
+  % that to the current nominal size.
+  % 
+  % By the way, simply using "at 1em" works for cmr10 and the like, but
+  % does not work for cmbx10 and other extended/shrunken fonts.
+  % 
+  \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+  %
+  \ifx\curfontstyle\bfstylename 
+    % bold:
+    \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+  \else 
+    % regular:
+    \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+  \fi
+  \thiseurofont
+}
+
+% @registeredsymbol - R in a circle.  The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+  $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+               \hfil\crcr\Orb}}%
+    }$%
+}
+
+% Laurent Siebenmann reports \Orb undefined with:
+%  Textures 1.7.7 (preloaded format=plain 93.10.14)  (68K)  16 APR 2004 02:38
+% so we'll define it if necessary.
+% 
+\ifx\Orb\undefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page.  Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+        \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+  % Open one extra group, as we want to close it in the middle of \Etitlepage.
+  \begingroup
+    \parindent=0pt \textfonts
+    % Leave some space at the very top of the page.
+    \vglue\titlepagetopglue
+    % No rule at page bottom unless we print one at the top with @title.
+    \finishedtitlepagetrue
+    %
+    % Most title ``pages'' are actually two pages long, with space
+    % at the top of the second.  We don't want the ragged left on the second.
+    \let\oldpage = \page
+    \def\page{%
+      \iffinishedtitlepage\else
+        \finishtitlepage
+      \fi
+      \let\page = \oldpage
+      \page
+      \null
+    }%
+}
+
+\def\Etitlepage{%
+    \iffinishedtitlepage\else
+       \finishtitlepage
+    \fi
+    % It is important to do the page break before ending the group,
+    % because the headline and footline are only empty inside the group.
+    % If we use the new definition of \page, we always get a blank page
+    % after the title page, which we certainly don't want.
+    \oldpage
+  \endgroup
+  %
+  % Need this before the \...aftertitlepage checks so that if they are
+  % in effect the toc pages will come out with page numbers.
+  \HEADINGSon
+  %
+  % If they want short, they certainly want long too.
+  \ifsetshortcontentsaftertitlepage
+    \shortcontents
+    \contents
+    \global\let\shortcontents = \relax
+    \global\let\contents = \relax
+  \fi
+  %
+  \ifsetcontentsaftertitlepage
+    \contents
+    \global\let\contents = \relax
+    \global\let\shortcontents = \relax
+  \fi
+}
+
+\def\finishtitlepage{%
+  \vskip4pt \hrule height 2pt width \hsize
+  \vskip\titlepagebottomglue
+  \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+               \let\tt=\authortt}
+
+\parseargdef\title{%
+  \checkenv\titlepage
+  \leftline{\titlefonts\rm #1}
+  % print a rule at the page bottom also.
+  \finishedtitlepagefalse
+  \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+  \checkenv\titlepage
+  {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+  \def\temp{\quotation}%
+  \ifx\thisenv\temp
+    \def\quotationauthor{#1}% printed in \Equotation.
+  \else
+    \checkenv\titlepage
+    \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+    {\authorfont \leftline{#1}}%
+  \fi
+}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline    % headline on even pages
+\newtoks\oddheadline     % headline on odd pages
+\newtoks\evenfootline    % footline on even pages
+\newtoks\oddfootline     % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+                            \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+                            \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what  @headings on  does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+  \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+  %
+  % Leave some space for the footline.  Hopefully ok to assume
+  % @evenfooting will not be used by itself.
+  \global\advance\pageheight by -\baselineskip
+  \global\advance\vsize by -\baselineskip
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+
+% @headings double      turns headings on for double-sided printing.
+% @headings single      turns headings on for single-sided printing.
+% @headings off         turns them off.
+% @headings on          same as @headings double, retained for compatibility.
+% @headings after       turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+  \number\day\space
+  \ifcase\month
+  \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+  \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+  \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+  \fi
+  \space\number\year}
+\fi
+
+% @settitle line...  specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent  \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin  \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+  \advance\hsize by -\rightskip
+  \advance\hsize by -\tableindent
+  \setbox0=\hbox{\itemindicate{#1}}%
+  \itemindex{#1}%
+  \nobreak % This prevents a break before @itemx.
+  %
+  % If the item text does not fit in the space we have, put it on a line
+  % by itself, and do not allow a page break either before or after that
+  % line.  We do not start a paragraph here because then if the next
+  % command is, e.g., @kindex, the whatsit would get put into the
+  % horizontal list on a line by itself, resulting in extra blank space.
+  \ifdim \wd0>\itemmax
+    %
+    % Make this a paragraph so we get the \parskip glue and wrapping,
+    % but leave it ragged-right.
+    \begingroup
+      \advance\leftskip by-\tableindent
+      \advance\hsize by\tableindent
+      \advance\rightskip by0pt plus1fil
+      \leavevmode\unhbox0\par
+    \endgroup
+    %
+    % We're going to be starting a paragraph, but we don't want the
+    % \parskip glue -- logically it's part of the @item we just started.
+    \nobreak \vskip-\parskip
+    %
+    % Stop a page break at the \parskip glue coming up.  However, if
+    % what follows is an environment such as @example, there will be no
+    % \parskip glue; then the negative vskip we just inserted would
+    % cause the example and the item to crash together.  So we use this
+    % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+    % \parskip glue after all.  Section titles are handled this way also.
+    % 
+    \penalty 10001
+    \endgroup
+    \itemxneedsnegativevskipfalse
+  \else
+    % The item text fits into the space.  Start a paragraph, so that the
+    % following text (if any) will end up on the same line.
+    \noindent
+    % Do this with kerns and \unhbox so that if there is a footnote in
+    % the item text, it can migrate to the main vertical list and
+    % eventually be printed.
+    \nobreak\kern-\tableindent
+    \dimen0 = \itemmax  \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+    \unhbox0
+    \nobreak\kern\dimen0
+    \endgroup
+    \itemxneedsnegativevskiptrue
+  \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+  \let\itemindex\gobble
+  \tablecheck{table}%
+}
+\envdef\ftable{%
+  \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+  \tablecheck{ftable}%
+}
+\envdef\vtable{%
+  \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+  \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+  \ifnum \the\catcode`\^^M=\active
+    \endgroup
+    \errmessage{This command won't work in this context; perhaps the problem is
+      that we are \inenvironment\thisenv}%
+    \def\next{\doignore{#1}}%
+  \else
+    \let\next\tablex
+  \fi
+  \next
+}
+\def\tablex#1{%
+  \def\itemindicate{#1}%
+  \parsearg\tabley
+}
+\def\tabley#1{%
+  {%
+    \makevalueexpandable
+    \edef\temp{\noexpand\tablez #1\space\space\space}%
+    \expandafter
+  }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+  \aboveenvbreak
+  \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+  \ifnum 0#2>0 \tableindent=#2\mil \fi
+  \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+  \itemmax=\tableindent
+  \advance \itemmax by -\itemmargin
+  \advance \leftskip by \tableindent
+  \exdentamount=\tableindent
+  \parindent = 0pt
+  \parskip = \smallskipamount
+  \ifdim \parskip=0pt \parskip=2pt \fi
+  \let\item = \internalBitem
+  \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+  \aboveenvbreak
+  \itemmax=\itemindent
+  \advance\itemmax by -\itemmargin
+  \advance\leftskip by \itemindent
+  \exdentamount=\itemindent
+  \parindent=0pt
+  \parskip=\smallskipamount
+  \ifdim\parskip=0pt \parskip=2pt \fi
+  \def\itemcontents{#1}%
+  % @itemize with no arg is equivalent to @itemize @bullet.
+  \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+  \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+  \advance\itemno by 1  % for enumerations
+  {\let\par=\endgraf \smallbreak}% reasonable place to break
+  {%
+   % If the document has an @itemize directly after a section title, a
+   % \nobreak will be last on the list, and \sectionheading will have
+   % done a \vskip-\parskip.  In that case, we don't want to zero
+   % parskip, or the item text will crash with the heading.  On the
+   % other hand, when there is normal text preceding the item (as there
+   % usually is), we do want to zero parskip, or there would be too much
+   % space.  In that case, we won't have a \nobreak before.  At least
+   % that's the theory.
+   \ifnum\lastpenalty<10000 \parskip=0in \fi
+   \noindent
+   \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+   \vadjust{\penalty 1200}}% not good to break after first line of item.
+  \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list.  No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1  \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+  % If we were given no argument, pretend we were given `1'.
+  \def\thearg{#1}%
+  \ifx\thearg\empty \def\thearg{1}\fi
+  %
+  % Detect if the argument is a single token.  If so, it might be a
+  % letter.  Otherwise, the only valid thing it can be is a number.
+  % (We will always have one token, because of the test we just made.
+  % This is a good thing, since \splitoff doesn't work given nothing at
+  % all -- the first parameter is undelimited.)
+  \expandafter\splitoff\thearg\endmark
+  \ifx\rest\empty
+    % Only one token in the argument.  It could still be anything.
+    % A ``lowercase letter'' is one whose \lccode is nonzero.
+    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+    %   not equal to itself.
+    % Otherwise, we assume it's a number.
+    %
+    % We need the \relax at the end of the \ifnum lines to stop TeX from
+    % continuing to look for a <number>.
+    %
+    \ifnum\lccode\expandafter`\thearg=0\relax
+      \numericenumerate % a number (we hope)
+    \else
+      % It's a letter.
+      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+        \lowercaseenumerate % lowercase letter
+      \else
+        \uppercaseenumerate % uppercase letter
+      \fi
+    \fi
+  \else
+    % Multiple tokens in the argument.  We hope it's a number.
+    \numericenumerate
+  \fi
+}
+
+% An @enumerate whose labels are integers.  The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+  \itemno = \thearg
+  \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more lowercase letters in @enumerate; get a bigger
+                  alphabet}%
+    \fi
+    \char\lccode\itemno
+  }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more uppercase letters in @enumerate; get a bigger
+                  alphabet}
+    \fi
+    \char\uccode\itemno
+  }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments.  Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+  \advance\itemno by -1
+  \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble.  Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+%   @multitable @columnfractions .25 .3 .45
+%   @item ...
+%
+%   Numbers following @columnfractions are the percent of the total
+%   current hsize to be used for each column. You may use as many
+%   columns as desired.
+
+
+% Or use a template:
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item ...
+%   using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item first col stuff @tab second col stuff @tab third col
+%   @item
+%   first col stuff
+%   @tab
+%   second col stuff
+%   @tab
+%   third col
+%   @item first col stuff @tab second col stuff
+%   @tab Many paragraphs of text may be used in any column.
+%
+%         They will wrap at the width determined by the template.
+%   @item@tab@tab This will be in third column.
+%   @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+%                                                            to baseline.
+%   0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1.  We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+  \global\advance\colcount by 1
+  \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+  \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+  \def\firstarg{#1}%
+  \ifx\firstarg\xendsetuptable
+    \let\go = \relax
+  \else
+    \ifx\firstarg\xcolumnfractions
+      \global\setpercenttrue
+    \else
+      \ifsetpercent
+         \let\go\pickupwholefraction
+      \else
+         \global\advance\colcount by 1
+         \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+                   % separator; typically that is always in the input, anyway.
+         \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+      \fi
+    \fi
+    \ifx\go\pickupwholefraction
+      % Put the argument back for the \pickupwholefraction call, so
+      % we'll always have a period there to be parsed.
+      \def\go{\pickupwholefraction#1}%
+    \else
+      \let\go = \setuptable
+    \fi%
+  \fi
+  \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry.  Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+%
+% A \tab used to include \hskip1sp.  But then the space in a template
+% line is not enough.  That is bad.  So let's go back to just `&' until
+% we encounter the problem it was intended to solve again.
+%                                      --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab  % insert after every tab.
+%
+\envdef\multitable{%
+  \vskip\parskip
+  \startsavinginserts
+  %
+  % @item within a multitable starts a normal row.
+  % We use \def instead of \let so that if one of the multitable entries
+  % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+  % \endtemplate) expanding \doitemize.
+  \def\item{\crcr}%
+  %
+  \tolerance=9500
+  \hbadness=9500
+  \setmultitablespacing
+  \parskip=\multitableparskip
+  \parindent=\multitableparindent
+  \overfullrule=0pt
+  \global\colcount=0
+  %
+  \everycr = {%
+    \noalign{%
+      \global\everytab={}%
+      \global\colcount=0 % Reset the column counter.
+      % Check for saved footnotes, etc.
+      \checkinserts
+      % Keeps underfull box messages off when table breaks over pages.
+      %\filbreak
+       % Maybe so, but it also creates really weird page breaks when the
+       % table breaks over pages. Wouldn't \vfil be better?  Wait until the
+       % problem manifests itself, so it can be fixed for real --karl.
+    }%
+  }%
+  %
+  \parsearg\domultitable
+}
+\def\domultitable#1{%
+  % To parse everything between @multitable and @item:
+  \setuptable#1 \endsetuptable
+  %
+  % This preamble sets up a generic column definition, which will
+  % be used as many times as user calls for columns.
+  % \vtop will set a single line and will also let text wrap and
+  % continue for many paragraphs if desired.
+  \halign\bgroup &%
+    \global\advance\colcount by 1
+    \multistrut
+    \vtop{%
+      % Use the current \colcount to find the correct column width:
+      \hsize=\expandafter\csname col\the\colcount\endcsname
+      %
+      % In order to keep entries from bumping into each other
+      % we will add a \leftskip of \multitablecolspace to all columns after
+      % the first one.
+      %
+      % If a template has been used, we will add \multitablecolspace
+      % to the width of each template entry.
+      %
+      % If the user has set preamble in terms of percent of \hsize we will
+      % use that dimension as the width of the column, and the \leftskip
+      % will keep entries from bumping into each other.  Table will start at
+      % left margin and final column will justify at right margin.
+      %
+      % Make sure we don't inherit \rightskip from the outer environment.
+      \rightskip=0pt
+      \ifnum\colcount=1
+       % The first column will be indented with the surrounding text.
+       \advance\hsize by\leftskip
+      \else
+       \ifsetpercent \else
+         % If user has not set preamble in terms of percent of \hsize
+         % we will advance \hsize by \multitablecolspace.
+         \advance\hsize by \multitablecolspace
+       \fi
+       % In either case we will make \leftskip=\multitablecolspace:
+      \leftskip=\multitablecolspace
+      \fi
+      % Ignoring space at the beginning and end avoids an occasional spurious
+      % blank line, when TeX decides to break the line at the space before the
+      % box from the multistrut, so the strut ends up on a line by itself.
+      % For example:
+      % @multitable @columnfractions .11 .89
+      % @item @code{#}
+      % @tab Legal holiday which is valid in major parts of the whole country.
+      % Is automatically provided with highlighting sequences respectively
+      % marking characters.
+      \noindent\ignorespaces##\unskip\multistrut
+    }\cr
+}
+\def\Emultitable{%
+  \crcr
+  \egroup % end the \halign
+  \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+  \def\multistrut{\strut}% just use the standard line spacing
+  %
+  % Compute \multitablelinespace (if not defined by user) for use in
+  % \multitableparskip calculation.  We used define \multistrut based on
+  % this, but (ironically) that caused the spacing to be off.
+  % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%%        If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed.  They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested.  But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+  \expandafter\let\csname #1\endcsname = \relax
+  \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+  % Scan in ``verbatim'' mode:
+  \catcode`\@ = \other
+  \catcode`\{ = \other
+  \catcode`\} = \other
+  %
+  % Make sure that spaces turn into tokens that match what \doignoretext wants.
+  \spaceisspace
+  %
+  % Count number of #1's that we've seen.
+  \doignorecount = 0
+  %
+  % Swallow text until we reach the matching `@end #1'.
+  \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+  \obeylines %
+  %
+  \gdef\dodoignore#1{%
+    % #1 contains the command name as a string, e.g., `ifinfo'.
+    %
+    % Define a command to find the next `@end #1', which must be on a line
+    % by itself.
+    \long\def\doignoretext##1^^M@end #1{\doignoretextyyy##1^^M@#1\_STOP_}%
+    % And this command to find another #1 command, at the beginning of a
+    % line.  (Otherwise, we would consider a line `@c @ifset', for
+    % example, to count as an @ifset for nesting.)
+    \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+    %
+    % And now expand that command.
+    \obeylines %
+    \doignoretext ^^M%
+  }%
+}
+
+\def\doignoreyyy#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty                      % Nothing found.
+    \let\next\doignoretextzzz
+  \else                                        % Found a nested condition, ...
+    \advance\doignorecount by 1
+    \let\next\doignoretextyyy          % ..., look for another.
+    % If we're here, #1 ends with ^^M\ifinfo (for example).
+  \fi
+  \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+  \ifnum\doignorecount = 0     % We have just found the outermost @end.
+    \let\next\enddoignore
+  \else                                % Still inside a nested condition.
+    \advance\doignorecount by -1
+    \let\next\doignoretext      % Look for the next @end.
+  \fi
+  \next
+}
+
+% Finish off ignored text.
+\def\enddoignore{\endgroup\ignorespaces}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+  {%
+    \makevalueexpandable
+    \def\temp{#2}%
+    \edef\next{\gdef\makecsname{SET#1}}%
+    \ifx\temp\empty
+      \next{}%
+    \else
+      \setzzz#2\endsetzzz
+    \fi
+  }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+  {%
+    \makevalueexpandable
+    \global\expandafter\let\csname SET#1\endcsname=\relax
+  }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+  \catcode`\- = \active \catcode`\_ = \active
+  %
+  \gdef\makevalueexpandable{%
+    \let\value = \expandablevalue
+    % We don't want these characters active, ...
+    \catcode`\-=\other \catcode`\_=\other
+    % ..., but we might end up with active ones in the argument if
+    % we're called from @code, as @code{@value{foo-bar_}}, though.
+    % So \let them to their normal equivalents.
+    \let-\realdash \let_\normalunderscore
+  }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file.  This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+  \expandafter\ifx\csname SET#1\endcsname\relax
+    {[No value for ``#1'']}%
+    \message{Variable `#1', used in @value, is not set.}%
+  \else
+    \csname SET#1\endcsname
+  \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+  {%
+    \makevalueexpandable
+    \let\next=\empty
+    \expandafter\ifx\csname SET#2\endcsname\relax
+      #1% If not set, redefine \next.
+    \fi
+    \expandafter
+  }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY  -- specify a category of the dir file
+% which this file should belong to.  Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index.  The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%     % Define @#1index
+    \noexpand\doindex{#1}}
+}
+
+% @defindex foo  ==  \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%
+    \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar    makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar   similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+  % Only do \closeout if we haven't already done it, else we'll end up
+  % closing the target index.
+  \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+    % The \closeout helps reduce unnecessary open files; the limit on the
+    % Acorn RISC OS is a mere 16 files.
+    \expandafter\closeout\csname#2indfile\endcsname
+    \expandafter\let\csname\donesynindex#2\endcsname = 1
+  \fi
+  % redefine \fooindfile:
+  \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+  \expandafter\let\csname#2indfile\endcsname=\temp
+  % redefine \fooindex:
+  \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+%  and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+  \escapechar = `\\     % use backslash in output files.
+  \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+  \def\ {\realbackslash\space }%
+  % Need these in case \tex is in effect and \{ is a \delimiter again.
+  % But can't use \lbracecmd and \rbracecmd because texindex assumes
+  % braces and backslashes are used only as delimiters.
+  \let\{ = \mylbrace
+  \let\} = \myrbrace
+  %
+  % Do the redefinitions.
+  \commondummies
+}
+
+% For the aux and toc files, @ is the escape character.  So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files).  When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+  \def\@{@@}%
+  \def\ {@ }%
+  \let\{ = \lbraceatcmd
+  \let\} = \rbraceatcmd
+  %
+  % Do the redefinitions.
+  \commondummies
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+  %
+  % \definedummyword defines \#1 as \string\#1\space, thus effectively
+  % preventing its expansion.  This is used only for control% words,
+  % not control letters, because the \space would be incorrect for
+  % control characters, but is needed to separate the control word
+  % from whatever follows.
+  %
+  % For control letters, we have \definedummyletter, which omits the
+  % space.
+  %
+  % These can be used both for control words that take an argument and
+  % those that do not.  If it is followed by {arg} in the input, then
+  % that will dutifully get written to the index (or wherever).
+  %
+  \def\definedummyword  ##1{\def##1{\string##1\space}}%
+  \def\definedummyletter##1{\def##1{\string##1}}%
+  \let\definedummyaccent\definedummyletter
+  %
+  \commondummiesnofonts
+  %
+  \definedummyletter\_%
+  %
+  % Non-English letters.
+  \definedummyword\AA
+  \definedummyword\AE
+  \definedummyword\L
+  \definedummyword\OE
+  \definedummyword\O
+  \definedummyword\aa
+  \definedummyword\ae
+  \definedummyword\l
+  \definedummyword\oe
+  \definedummyword\o
+  \definedummyword\ss
+  \definedummyword\exclamdown
+  \definedummyword\questiondown
+  \definedummyword\ordf
+  \definedummyword\ordm
+  %
+  % Although these internal commands shouldn't show up, sometimes they do.
+  \definedummyword\bf
+  \definedummyword\gtr
+  \definedummyword\hat
+  \definedummyword\less
+  \definedummyword\sf
+  \definedummyword\sl
+  \definedummyword\tclose
+  \definedummyword\tt
+  %
+  \definedummyword\LaTeX
+  \definedummyword\TeX
+  %
+  % Assorted special characters.
+  \definedummyword\bullet
+  \definedummyword\comma
+  \definedummyword\copyright
+  \definedummyword\registeredsymbol
+  \definedummyword\dots
+  \definedummyword\enddots
+  \definedummyword\equiv
+  \definedummyword\error
+  \definedummyword\euro
+  \definedummyword\expansion
+  \definedummyword\minus
+  \definedummyword\pounds
+  \definedummyword\point
+  \definedummyword\print
+  \definedummyword\result
+  %
+  % We want to disable all macros so that they are not expanded by \write.
+  \macrolist
+  %
+  \normalturnoffactive
+  %
+  % Handle some cases of @value -- where it does not contain any
+  % (non-fully-expandable) commands.
+  \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+% Better have this without active chars.
+{
+  \catcode`\~=\other
+  \gdef\commondummiesnofonts{%
+    % Control letters and accents.
+    \definedummyletter\!%
+    \definedummyaccent\"%
+    \definedummyaccent\'%
+    \definedummyletter\*%
+    \definedummyaccent\,%
+    \definedummyletter\.%
+    \definedummyletter\/%
+    \definedummyletter\:%
+    \definedummyaccent\=%
+    \definedummyletter\?%
+    \definedummyaccent\^%
+    \definedummyaccent\`%
+    \definedummyaccent\~%
+    \definedummyword\u
+    \definedummyword\v
+    \definedummyword\H
+    \definedummyword\dotaccent
+    \definedummyword\ringaccent
+    \definedummyword\tieaccent
+    \definedummyword\ubaraccent
+    \definedummyword\udotaccent
+    \definedummyword\dotless
+    %
+    % Texinfo font commands.
+    \definedummyword\b
+    \definedummyword\i
+    \definedummyword\r
+    \definedummyword\sc
+    \definedummyword\t
+    %
+    % Commands that take arguments.
+    \definedummyword\acronym
+    \definedummyword\cite
+    \definedummyword\code
+    \definedummyword\command
+    \definedummyword\dfn
+    \definedummyword\emph
+    \definedummyword\env
+    \definedummyword\file
+    \definedummyword\kbd
+    \definedummyword\key
+    \definedummyword\math
+    \definedummyword\option
+    \definedummyword\samp
+    \definedummyword\strong
+    \definedummyword\tie
+    \definedummyword\uref
+    \definedummyword\url
+    \definedummyword\var
+    \definedummyword\verb
+    \definedummyword\w
+  }
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names.  It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+  % Accent commands should become @asis.
+  \def\definedummyaccent##1{\let##1\asis}%
+  % We can just ignore other control letters.
+  \def\definedummyletter##1{\let##1\empty}%
+  % Hopefully, all control words can become @asis.
+  \let\definedummyword\definedummyaccent
+  %
+  \commondummiesnofonts
+  %
+  % Don't no-op \tt, since it isn't a user-level command
+  % and is used in the definitions of the active chars like <, >, |, etc.
+  % Likewise with the other plain tex font commands.
+  %\let\tt=\asis
+  %
+  \def\ { }%
+  \def\@{@}%
+  % how to handle braces?
+  \def\_{\normalunderscore}%
+  %
+  % Non-English letters.
+  \def\AA{AA}%
+  \def\AE{AE}%
+  \def\L{L}%
+  \def\OE{OE}%
+  \def\O{O}%
+  \def\aa{aa}%
+  \def\ae{ae}%
+  \def\l{l}%
+  \def\oe{oe}%
+  \def\o{o}%
+  \def\ss{ss}%
+  \def\exclamdown{!}%
+  \def\questiondown{?}%
+  \def\ordf{a}%
+  \def\ordm{o}%
+  %
+  \def\LaTeX{LaTeX}%
+  \def\TeX{TeX}%
+  %
+  % Assorted special characters.
+  % (The following {} will end up in the sort string, but that's ok.)
+  \def\bullet{bullet}%
+  \def\comma{,}%
+  \def\copyright{copyright}%
+  \def\registeredsymbol{R}%
+  \def\dots{...}%
+  \def\enddots{...}%
+  \def\equiv{==}%
+  \def\error{error}%
+  \def\euro{euro}%
+  \def\expansion{==>}%
+  \def\minus{-}%
+  \def\pounds{pounds}%
+  \def\point{.}%
+  \def\print{-|}%
+  \def\result{=>}%
+  %
+  % We need to get rid of all macros, leaving only the arguments (if present).
+  % Of course this is not nearly correct, but it is the best we can do for now.
+  % makeinfo does not expand macros in the argument to @deffn, which ends up
+  % writing an index entry, and texindex isn't prepared for an index sort entry
+  % that starts with \.
+  % 
+  % Since macro invocations are followed by braces, we can just redefine them
+  % to take a single TeX argument.  The case of a macro invocation that
+  % goes to end-of-line is not handled.
+  % 
+  \macrolist
+}
+
+\let\indexbackslash=0  %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+  \iflinks
+  {%
+    % Store the main index entry text (including the third arg).
+    \toks0 = {#2}%
+    % If third arg is present, precede it with a space.
+    \def\thirdarg{#3}%
+    \ifx\thirdarg\empty \else
+      \toks0 = \expandafter{\the\toks0 \space #3}%
+    \fi
+    %
+    \edef\writeto{\csname#1indfile\endcsname}%
+    %
+    \ifvmode
+      \dosubindsanitize
+    \else
+      \dosubindwrite
+    \fi
+  }%
+  \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+  % Put the index entry in the margin if desired.
+  \ifx\SETmarginindex\relax\else
+    \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+  \fi
+  %
+  % Remember, we are within a group.
+  \indexdummies % Must do this here, since \bf, etc expand at this stage
+  \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+      % so it will be output as is; and it will print as backslash.
+  %
+  % Process the index entry with all font commands turned off, to
+  % get the string to sort by.
+  {\indexnofonts
+   \edef\temp{\the\toks0}% need full expansion
+   \xdef\indexsorttmp{\temp}%
+  }%
+  %
+  % Set up the complete index entry, with both the sort key and
+  % the original text, including any font commands.  We write
+  % three arguments to \entry to the .?? file (four in the
+  % subentry case), texindex reduces to two when writing the .??s
+  % sorted result.
+  \edef\temp{%
+    \write\writeto{%
+      \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+  }%
+  \temp
+}
+
+% Take care of unwanted page breaks:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again.  Otherwise, the whatsit generated by the
+% \write will make \lastskip zero.  The result is that sequences
+% like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode.  We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip.  \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip.  The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+% ..., ready, GO:
+%
+\def\dosubindsanitize{%
+  % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+  \skip0 = \lastskip
+  \edef\lastskipmacro{\the\lastskip}%
+  \count255 = \lastpenalty
+  %
+  % If \lastskip is nonzero, that means the last item was a
+  % skip.  And since a skip is discardable, that means this
+  % -\skip0 glue we're inserting is preceded by a
+  % non-discardable item, therefore it is not a potential
+  % breakpoint, therefore no \nobreak needed.
+  \ifx\lastskipmacro\zeroskipmacro
+  \else
+    \vskip-\skip0
+  \fi
+  %
+  \dosubindwrite
+  %
+  \ifx\lastskipmacro\zeroskipmacro
+    % If \lastskip was zero, perhaps the last item was a penalty, and
+    % perhaps it was >=10000, e.g., a \nobreak.  In that case, we want
+    % to re-insert the same penalty (values >10000 are used for various
+    % signals); since we just inserted a non-discardable item, any
+    % following glue (such as a \parskip) would be a breakpoint.  For example:
+    % 
+    %   @deffn deffn-whatever
+    %   @vindex index-whatever
+    %   Description.
+    % would allow a break between the index-whatever whatsit
+    % and the "Description." paragraph.
+    \ifnum\count255>9999 \penalty\count255 \fi
+  \else
+    % On the other hand, if we had a nonzero \lastskip,
+    % this make-up glue would be preceded by a non-discardable item
+    % (the whatsit from the \write), so we must insert a \nobreak.
+    \nobreak\vskip\skip0
+  \fi
+}
+
+% The index entry written in the file actually looks like
+%  \entry {sortstring}{page}{topic}
+% or
+%  \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+%  \initial {c}
+%     before the first topic whose initial is c
+%  \entry {topic}{pagelist}
+%     for a topic that is used without subtopics
+%  \primary {topic}
+%     for the beginning of a topic that is used with subtopics
+%  \secondary {subtopic}{pagelist}
+%     for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+  \dobreak \chapheadingskip{10000}%
+  %
+  \smallfonts \rm
+  \tolerance = 9500
+  \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+  %
+  % See if the index file exists and is nonempty.
+  % Change catcode of @ here so that if the index file contains
+  % \initial {@}
+  % as its first line, TeX doesn't complain about mismatched braces
+  % (because it thinks @} is a control sequence).
+  \catcode`\@ = 11
+  \openin 1 \jobname.#1s
+  \ifeof 1
+    % \enddoublecolumns gets confused if there is no text in the index,
+    % and it loses the chapter title and the aux file entries for the
+    % index.  The easiest way to prevent this problem is to make sure
+    % there is some text.
+    \putwordIndexNonexistent
+  \else
+    %
+    % If the index file exists but is empty, then \openin leaves \ifeof
+    % false.  We have to make TeX try to read something from the file, so
+    % it can discover if there is anything in it.
+    \read 1 to \temp
+    \ifeof 1
+      \putwordIndexIsEmpty
+    \else
+      % Index files are almost Texinfo source, but we use \ as the escape
+      % character.  It would be better to use @, but that's too big a change
+      % to make right now.
+      \def\indexbackslash{\backslashcurfont}%
+      \catcode`\\ = 0
+      \escapechar = `\\
+      \begindoublecolumns
+      \input \jobname.#1s
+      \enddoublecolumns
+    \fi
+  \fi
+  \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+  % Some minor font changes for the special characters.
+  \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+  %
+  % Remove any glue we may have, we'll be inserting our own.
+  \removelastskip
+  %
+  % We like breaks before the index initials, so insert a bonus.
+  \nobreak
+  \vskip 0pt plus 3\baselineskip
+  \penalty 0
+  \vskip 0pt plus -3\baselineskip
+  %
+  % Typeset the initial.  Making this add up to a whole number of
+  % baselineskips increases the chance of the dots lining up from column
+  % to column.  It still won't often be perfect, because of the stretch
+  % we need before each entry, but it's better.
+  %
+  % No shrink because it confuses \balancecolumns.
+  \vskip 1.67\baselineskip plus .5\baselineskip
+  \leftline{\secbf #1}%
+  % Do our best not to break after the initial.
+  \nobreak
+  \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin.  It is used for index
+% and table of contents entries.  The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+%      \def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which sets - active.  This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% The right solution is to prevent \entry from swallowing the whole text.
+%                                 --kasal, 21nov03
+\def\entry{%
+  \begingroup
+    %
+    % Start a new paragraph if necessary, so our assignments below can't
+    % affect previous text.
+    \par
+    %
+    % Do not fill out the last line with white space.
+    \parfillskip = 0in
+    %
+    % No extra space above this paragraph.
+    \parskip = 0in
+    %
+    % Do not prefer a separate line ending with a hyphen to fewer lines.
+    \finalhyphendemerits = 0
+    %
+    % \hangindent is only relevant when the entry text and page number
+    % don't both fit on one line.  In that case, bob suggests starting the
+    % dots pretty far over on the line.  Unfortunately, a large
+    % indentation looks wrong when the entry text itself is broken across
+    % lines.  So we use a small indentation and put up with long leaders.
+    %
+    % \hangafter is reset to 1 (which is the value we want) at the start
+    % of each paragraph, so we need not do anything with that.
+    \hangindent = 2em
+    %
+    % When the entry text needs to be broken, just fill out the first line
+    % with blank space.
+    \rightskip = 0pt plus1fil
+    %
+    % A bit of stretch before each entry for the benefit of balancing
+    % columns.
+    \vskip 0pt plus1pt
+    %
+    % Swallow the left brace of the text (first parameter):
+    \afterassignment\doentry
+    \let\temp =
+}
+\def\doentry{%
+    \bgroup % Instead of the swallowed brace.
+      \noindent
+      \aftergroup\finishentry
+      % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+    % #1 is the page number.
+    %
+    % The following is kludged to not output a line of dots in the index if
+    % there are no page numbers.  The next person who breaks this will be
+    % cursed by a Unix daemon.
+    \def\tempa{{\rm }}%
+    \def\tempb{#1}%
+    \edef\tempc{\tempa}%
+    \edef\tempd{\tempb}%
+    \ifx\tempc\tempd
+      \ %
+    \else
+      %
+      % If we must, put the page number on a line of its own, and fill out
+      % this line with blank space.  (The \hfil is overwhelmed with the
+      % fill leaders glue in \indexdotfill if the page number does fit.)
+      \hfil\penalty50
+      \null\nobreak\indexdotfill % Have leaders before the page number.
+      %
+      % The `\ ' here is removed by the implicit \unskip that TeX does as
+      % part of (the primitive) \par.  Without it, a spurious underfull
+      % \hbox ensues.
+      \ifpdf
+       \pdfgettoks#1.%
+       \ \the\toksA
+      \else
+       \ #1%
+      \fi
+    \fi
+    \par
+  \endgroup
+}
+
+% Like \dotfill except takes at least 1 em.
+\def\indexdotfill{\cleaders
+  \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+  \parfillskip=0in
+  \parskip=0in
+  \hangindent=1in
+  \hangafter=1
+  \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+  \ifpdf
+    \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+  \else
+    #2
+  \fi
+  \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+  % Grab any single-column material above us.
+  \output = {%
+    %
+    % Here is a possibility not foreseen in manmac: if we accumulate a
+    % whole lot of material, we might end up calling this \output
+    % routine twice in a row (see the doublecol-lose test, which is
+    % essentially a couple of indexes with @setchapternewpage off).  In
+    % that case we just ship out what is in \partialpage with the normal
+    % output routine.  Generally, \partialpage will be empty when this
+    % runs and this will be a no-op.  See the indexspread.tex test case.
+    \ifvoid\partialpage \else
+      \onepageout{\pagecontents\partialpage}%
+    \fi
+    %
+    \global\setbox\partialpage = \vbox{%
+      % Unvbox the main output page.
+      \unvbox\PAGE
+      \kern-\topskip \kern\baselineskip
+    }%
+  }%
+  \eject % run that output routine to set \partialpage
+  %
+  % Use the double-column output routine for subsequent pages.
+  \output = {\doublecolumnout}%
+  %
+  % Change the page size parameters.  We could do this once outside this
+  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+  % format, but then we repeat the same computation.  Repeating a couple
+  % of assignments once per index is clearly meaningless for the
+  % execution time, so we may as well do it in one place.
+  %
+  % First we halve the line length, less a little for the gutter between
+  % the columns.  We compute the gutter based on the line length, so it
+  % changes automatically with the paper format.  The magic constant
+  % below is chosen so that the gutter has the same value (well, +-<1pt)
+  % as it did when we hard-coded it.
+  %
+  % We put the result in a separate register, \doublecolumhsize, so we
+  % can restore it in \pagesofar, after \hsize itself has (potentially)
+  % been clobbered.
+  %
+  \doublecolumnhsize = \hsize
+    \advance\doublecolumnhsize by -.04154\hsize
+    \divide\doublecolumnhsize by 2
+  \hsize = \doublecolumnhsize
+  %
+  % Double the \vsize as well.  (We don't need a separate register here,
+  % since nobody clobbers \vsize.)
+  \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+  \splittopskip=\topskip \splitmaxdepth=\maxdepth
+  % Get the available space for the double columns -- the normal
+  % (undoubled) page height minus any material left over from the
+  % previous page.
+  \dimen@ = \vsize
+  \divide\dimen@ by 2
+  \advance\dimen@ by -\ht\partialpage
+  %
+  % box0 will be the left-hand column, box2 the right.
+  \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+  \onepageout\pagesofar
+  \unvbox255
+  \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+  \unvbox\partialpage
+  %
+  \hsize = \doublecolumnhsize
+  \wd0=\hsize \wd2=\hsize
+  \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+  \output = {%
+    % Split the last of the double-column material.  Leave it on the
+    % current page, no automatic page break.
+    \balancecolumns
+    %
+    % If we end up splitting too much material for the current page,
+    % though, there will be another page break right after this \output
+    % invocation ends.  Having called \balancecolumns once, we do not
+    % want to call it again.  Therefore, reset \output to its normal
+    % definition right away.  (We hope \balancecolumns will never be
+    % called on to balance too much material, but if it is, this makes
+    % the output somewhat more palatable.)
+    \global\output = {\onepageout{\pagecontents\PAGE}}%
+  }%
+  \eject
+  \endgroup % started in \begindoublecolumns
+  %
+  % \pagegoal was set to the doubled \vsize above, since we restarted
+  % the current page.  We're now back to normal single-column
+  % typesetting, so reset \pagegoal to the normal \vsize (after the
+  % \endgroup where \vsize got restored).
+  \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+  \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+  \dimen@ = \ht0
+  \advance\dimen@ by \topskip
+  \advance\dimen@ by-\baselineskip
+  \divide\dimen@ by 2 % target to split to
+  %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+  \splittopskip = \topskip
+  % Loop until we get a decent breakpoint.
+  {%
+    \vbadness = 10000
+    \loop
+      \global\setbox3 = \copy0
+      \global\setbox1 = \vsplit3 to \dimen@
+    \ifdim\ht3>\dimen@
+      \global\advance\dimen@ by 1pt
+    \repeat
+  }%
+  %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+  \setbox0=\vbox to\dimen@{\unvbox1}%
+  \setbox2=\vbox to\dimen@{\unvbox3}%
+  %
+  \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course.  But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number".  We avoid collisions with chapter
+% numbers by starting them at 10000.  (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno        \secno=0
+\newcount\subsecno     \subsecno=0
+\newcount\subsubsecno  \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno  \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+  \ifnum\appendixno=`A A%
+  \else\ifnum\appendixno=`B B%
+  \else\ifnum\appendixno=`C C%
+  \else\ifnum\appendixno=`D D%
+  \else\ifnum\appendixno=`E E%
+  \else\ifnum\appendixno=`F F%
+  \else\ifnum\appendixno=`G G%
+  \else\ifnum\appendixno=`H H%
+  \else\ifnum\appendixno=`I I%
+  \else\ifnum\appendixno=`J J%
+  \else\ifnum\appendixno=`K K%
+  \else\ifnum\appendixno=`L L%
+  \else\ifnum\appendixno=`M M%
+  \else\ifnum\appendixno=`N N%
+  \else\ifnum\appendixno=`O O%
+  \else\ifnum\appendixno=`P P%
+  \else\ifnum\appendixno=`Q Q%
+  \else\ifnum\appendixno=`R R%
+  \else\ifnum\appendixno=`S S%
+  \else\ifnum\appendixno=`T T%
+  \else\ifnum\appendixno=`U U%
+  \else\ifnum\appendixno=`V V%
+  \else\ifnum\appendixno=`W W%
+  \else\ifnum\appendixno=`X X%
+  \else\ifnum\appendixno=`Y Y%
+  \else\ifnum\appendixno=`Z Z%
+  % The \the is necessary, despite appearances, because \appendixletter is
+  % expanded while writing the .toc file.  \char\appendixno is not
+  % expandable, thus it is written literally, thus all appendixes come out
+  % with the same letter (or @) in the toc without it.
+  \else\char\the\appendixno
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it.  @section does likewise.
+% However, they are not reliable, because we don't use marks.
+\def\thischapter{}
+\def\thissection{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+  % Compute the abs. sec. level:
+  \absseclevel=#2
+  \advance\absseclevel by \secbase
+  % Make sure \absseclevel doesn't fall outside the range:
+  \ifnum \absseclevel < 0
+    \absseclevel = 0
+  \else
+    \ifnum \absseclevel > 3
+      \absseclevel = 3
+    \fi
+  \fi
+  % The heading type:
+  \def\headtype{#1}%
+  \if \headtype U%
+    \ifnum \absseclevel < \unmlevel
+      \chardef\unmlevel = \absseclevel
+    \fi
+  \else
+    % Check for appendix sections:
+    \ifnum \absseclevel = 0
+      \edef\chapheadtype{\headtype}%
+    \else
+      \if \headtype A\if \chapheadtype N%
+       \errmessage{@appendix... within a non-appendix chapter}%
+      \fi\fi
+    \fi
+    % Check for numbered within unnumbered:
+    \ifnum \absseclevel > \unmlevel
+      \def\headtype{U}%
+    \else
+      \chardef\unmlevel = 3
+    \fi
+  \fi
+  % Now print the heading:
+  \if \headtype U%
+    \ifcase\absseclevel
+       \unnumberedzzz{#3}%
+    \or \unnumberedseczzz{#3}%
+    \or \unnumberedsubseczzz{#3}%
+    \or \unnumberedsubsubseczzz{#3}%
+    \fi
+  \else
+    \if \headtype A%
+      \ifcase\absseclevel
+         \appendixzzz{#3}%
+      \or \appendixsectionzzz{#3}%
+      \or \appendixsubseczzz{#3}%
+      \or \appendixsubsubseczzz{#3}%
+      \fi
+    \else
+      \ifcase\absseclevel
+         \chapterzzz{#3}%
+      \or \seczzz{#3}%
+      \or \numberedsubseczzz{#3}%
+      \or \numberedsubsubseczzz{#3}%
+      \fi
+    \fi
+  \fi
+  \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered.  Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v.  By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+  % section resetting is \global in case the chapter is in a group, such
+  % as an @include file.
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\chapno by 1
+  %
+  % Used for \float.
+  \gdef\chaplevelprefix{\the\chapno.}%
+  \resetallfloatnos
+  %
+  \message{\putwordChapter\space \the\chapno}%
+  %
+  % Write the actual heading.
+  \chapmacro{#1}{Ynumbered}{\the\chapno}%
+  %
+  % So @section and the like are numbered underneath this chapter.
+  \global\let\section = \numberedsec
+  \global\let\subsection = \numberedsubsec
+  \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\appendixno by 1
+  \gdef\chaplevelprefix{\appendixletter.}%
+  \resetallfloatnos
+  %
+  \def\appendixnum{\putwordAppendix\space \appendixletter}%
+  \message{\appendixnum}%
+  %
+  \chapmacro{#1}{Yappendix}{\appendixletter}%
+  %
+  \global\let\section = \appendixsec
+  \global\let\subsection = \appendixsubsec
+  \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\unnumberedno by 1
+  %
+  % Since an unnumbered has no number, no prefix for figures.
+  \global\let\chaplevelprefix = \empty
+  \resetallfloatnos
+  %
+  % This used to be simply \message{#1}, but TeX fully expands the
+  % argument to \message.  Therefore, if #1 contained @-commands, TeX
+  % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
+  % expanded @cite (which turns out to cause errors because \cite is meant
+  % to be executed, not expanded).
+  %
+  % Anyway, we don't want the fully-expanded definition of @cite to appear
+  % as a result of the \message, we just want `@cite' itself.  We use
+  % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+  % simply yielding the contents of <toks register>.  (We also do this for
+  % the toc entries.)
+  \toks0 = {#1}%
+  \message{(\the\toks0)}%
+  %
+  \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+  %
+  \global\let\section = \unnumberedsec
+  \global\let\subsection = \unnumberedsubsec
+  \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+  % Well, we could do the following in a group, but that would break
+  % an assumption that \chapmacro is called at the outermost level.
+  % Thus we are safer this way:                --kasal, 24feb04
+  \let\centerparametersmaybe = \centerparameters
+  \unnmhead0{#1}%
+  \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynumbered}%
+                 {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+%       1) We use \vbox rather than the earlier \line to permit
+%          overlong headings to fold.
+%       2) \hyphenpenalty is set to 10000 because hyphenation in a
+%          heading is obnoxious; this forbids it.
+%       3) Likewise, headings look best if no \parindent is used, and
+%          if justification is not attempted.  Hence \raggedright.
+
+
+\def\majorheading{%
+  {\advance\chapheadingskip by 10pt \chapbreak }%
+  \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                    \parindent=0pt\raggedright
+                    \rm #1\hfill}}%
+  \bigskip \par\penalty 200\relax
+  \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+  \pchapsepmacro
+  {%
+    \chapfonts \rm
+    %
+    % Have to define \thissection before calling \donoderef, because the
+    % xref code eventually uses it.  On the other hand, it has to be called
+    % after \pchapsepmacro, or the headline will change too soon.
+    \gdef\thissection{#1}%
+    \gdef\thischaptername{#1}%
+    %
+    % Only insert the separating space if we have a chapter/appendix
+    % number, and don't print the unnumbered ``number''.
+    \def\temptype{#2}%
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unnchap}%
+      \gdef\thischapter{#1}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+      \def\toctype{omit}%
+      \gdef\thischapter{}%
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+      \def\toctype{app}%
+      % We don't substitute the actual chapter name into \thischapter
+      % because we don't want its macros evaluated now.  And we don't
+      % use \thissection because that changes with each section.
+      %
+      \xdef\thischapter{\putwordAppendix{} \appendixletter:
+                        \noexpand\thischaptername}%
+    \else
+      \setbox0 = \hbox{#3\enspace}%
+      \def\toctype{numchap}%
+      \xdef\thischapter{\putwordChapter{} \the\chapno:
+                        \noexpand\thischaptername}%
+    \fi\fi\fi
+    %
+    % Write the toc entry for this chapter.  Must come before the
+    % \donoderef, because we include the current node name in the toc
+    % entry, and \donoderef resets it to empty.
+    \writetocentry{\toctype}{#1}{#3}%
+    %
+    % For pdftex, we have to write out the node definition (aka, make
+    % the pdfdest) after any page break, but before the actual text has
+    % been typeset.  If the destination for the pdf outline is after the
+    % text, then jumping from the outline may wind up with the text not
+    % being visible, for instance under high magnification.
+    \donoderef{#2}%
+    %
+    % Typeset the actual heading.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0 \centerparametersmaybe
+          \unhbox0 #1\par}%
+  }%
+  \nobreak\bigskip % no page break after a chapter title
+  \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+  \advance\rightskip by 3\rightskip
+  \leftskip = \rightskip
+  \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff.  We'll see.  --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt\raggedright
+                       \rm #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt
+                       \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+  \global\let\chapmacro=\chfopen
+  \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles.  These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\sectionheading#1#2#3#4{%
+  {%
+    % Switch to the right set of fonts.
+    \csname #2fonts\endcsname \rm
+    %
+    % Insert space above the heading.
+    \csname #2headingbreak\endcsname
+    %
+    % Only insert the space after the number if we have a section number.
+    \def\sectionlevel{#2}%
+    \def\temptype{#3}%
+    %
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unn}%
+      \gdef\thissection{#1}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      % for @headings -- no section number, don't include in toc,
+      % and don't redefine \thissection.
+      \setbox0 = \hbox{}%
+      \def\toctype{omit}%
+      \let\sectionlevel=\empty
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{app}%
+      \gdef\thissection{#1}%
+    \else
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{num}%
+      \gdef\thissection{#1}%
+    \fi\fi\fi
+    %
+    % Write the toc entry (before \donoderef).  See comments in \chfplain.
+    \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+    %
+    % Write the node reference (= pdf destination for pdftex).
+    % Again, see comments in \chfplain.
+    \donoderef{#3}%
+    %
+    % Output the actual section heading.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0  % zero if no section number
+          \unhbox0 #1}%
+  }%
+  % Add extra space after the heading -- half of whatever came above it.
+  % Don't allow stretch, though.
+  \kern .5 \csname #2headingskip\endcsname
+  %
+  % Do not let the kern be a potential breakpoint, as it would be if it
+  % was followed by glue.
+  \nobreak
+  %
+  % We'll almost certainly start a paragraph next, so don't let that
+  % glue accumulate.  (Not a breakpoint because it's preceded by a
+  % discardable item.)
+  \vskip-\parskip
+  % 
+  % This is purely so the last item on the list is a known \penalty >
+  % 10000.  This is so \startdefun can avoid allowing breakpoints after
+  % section headings.  Otherwise, it would insert a valid breakpoint between:
+  % 
+  %   @section sec-whatever
+  %   @deffn def-whatever
+  \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this.  The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything.  This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+  \edef\writetoctype{#1}%
+  \ifx\writetoctype\omitkeyword \else
+    \iftocfileopened\else
+      \immediate\openout\tocfile = \jobname.toc
+      \global\tocfileopenedtrue
+    \fi
+    %
+    \iflinks
+      {\atdummies
+       \edef\temp{%
+         \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+       \temp
+      }
+    \fi
+  \fi
+  %
+  % Tell \shipout to create a pdf destination on each page, if we're
+  % writing pdf.  These are used in the table of contents.  We can't
+  % just write one on every page because the title pages are numbered
+  % 1 and 2 (the page numbers aren't printed), and so are the first
+  % two pages of the document.  Thus, we'd have two destinations named
+  % `1', and two named `2'.
+  \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care.  This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+% 
+\def\activecatcodes{%
+  \catcode`\"=\active
+  \catcode`\$=\active
+  \catcode`\<=\active
+  \catcode`\>=\active
+  \catcode`\\=\active
+  \catcode`\^=\active
+  \catcode`\_=\active
+  \catcode`\|=\active
+  \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+  \setupdatafile
+  \activecatcodes
+  \input \jobname.toc
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+  % If @setchapternewpage on, and @headings double, the contents should
+  % start on an odd page, unlike chapters.  Thus, we maintain
+  % \contentsalignmacro in parallel with \pagealignmacro.
+  % From: Torbjorn Granlund <tege@matematik.su.se>
+  \contentsalignmacro
+  \immediate\closeout\tocfile
+  %
+  % Don't need to put `Contents' or `Short Contents' in the headline.
+  % It is abundantly clear what they are.
+  \def\thischapter{}%
+  \chapmacro{#1}{Yomitfromtoc}{}%
+  %
+  \savepageno = \pageno
+  \begingroup                  % Set up to handle contents files properly.
+    \raggedbottom              % Worry more about breakpoints than the bottom.
+    \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+    %
+    % Roman numerals for page numbers.
+    \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+
+% Normal (long) toc.
+\def\contents{%
+  \startcontents{\putwordTOC}%
+    \openin 1 \jobname.toc
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+    \ifeof 1 \else
+      \pdfmakeoutlines
+    \fi
+    \closein 1
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+  \startcontents{\putwordShortTOC}%
+    %
+    \let\numchapentry = \shortchapentry
+    \let\appentry = \shortchapentry
+    \let\unnchapentry = \shortunnchapentry
+    % We want a true roman here for the page numbers.
+    \secfonts
+    \let\rm=\shortcontrm \let\bf=\shortcontbf
+    \let\sl=\shortcontsl \let\tt=\shortconttt
+    \rm
+    \hyphenpenalty = 10000
+    \advance\baselineskip by 1pt % Open it up a little.
+    \def\numsecentry##1##2##3##4{}
+    \let\appsecentry = \numsecentry
+    \let\unnsecentry = \numsecentry
+    \let\numsubsecentry = \numsecentry
+    \let\appsubsecentry = \numsecentry
+    \let\unnsubsecentry = \numsecentry
+    \let\numsubsubsecentry = \numsecentry
+    \let\appsubsubsecentry = \numsecentry
+    \let\unnsubsubsecentry = \numsecentry
+    \openin 1 \jobname.toc
+    \ifeof 1 \else
+      \readtocfile
+    \fi
+    \closein 1
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+  % This space should be enough, since a single number is .5em, and the
+  % widest letter (M) is 1em, at least in the Computer Modern fonts.
+  % But use \hss just in case.
+  % (This space doesn't include the extra space that gets added after
+  % the label; that gets put in by \shortchapentry above.)
+  %
+  % We'd like to right-justify chapter numbers, but that looks strange
+  % with appendix letters.  And right-justifying numbers and
+  % left-justifying letters looks strange when there is less than 10
+  % chapters.  Have to read the whole toc once to know how many chapters
+  % there are before deciding ...
+  \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+  % We use M since it's probably the widest letter.
+  \setbox0 = \hbox{\putwordAppendix{} M}%
+  \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+   \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+   \begingroup
+     \chapentryfonts
+     \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+   \endgroup
+   \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+  \secentryfonts \leftskip=\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+  \subsecentryfonts \leftskip=2\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+  \subsubsecentryfonts \leftskip=3\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+   \advance\hsize by -2\dimen2 % Rules.
+   \vbox{%
+      \hrule height\dimen2
+      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
+         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+         \kern3pt\vrule width\dimen2}% Space to right.
+      \hrule height\dimen2}
+    \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex    escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\envdef\tex{%
+  \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+  \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+  \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+  \catcode `\%=14
+  \catcode `\+=\other
+  \catcode `\"=\other
+  \catcode `\|=\other
+  \catcode `\<=\other
+  \catcode `\>=\other
+  \escapechar=`\\
+  %
+  \let\b=\ptexb
+  \let\bullet=\ptexbullet
+  \let\c=\ptexc
+  \let\,=\ptexcomma
+  \let\.=\ptexdot
+  \let\dots=\ptexdots
+  \let\equiv=\ptexequiv
+  \let\!=\ptexexclam
+  \let\i=\ptexi
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \let\{=\ptexlbrace
+  \let\+=\tabalign
+  \let\}=\ptexrbrace
+  \let\/=\ptexslash
+  \let\*=\ptexstar
+  \let\t=\ptext
+  \let\frenchspacing=\plainfrenchspacing
+  %
+  \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+  \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+  \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments.  \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical.  We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+  % =10000 instead of <10000 because of a special case in \itemzzz and
+  % \sectionheading, q.v.
+  \ifnum \lastpenalty=10000 \else
+    \advance\envskipamount by \parskip
+    \endgraf
+    \ifdim\lastskip<\envskipamount
+      \removelastskip
+      % it's not a good place to break if the last penalty was \nobreak
+      % or better ...
+      \ifnum\lastpenalty<10000 \penalty-50 \fi
+      \vskip\envskipamount
+    \fi
+  \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+        \ctl\leaders\hrule height\circthick\hfil\ctr
+        \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+        \cbl\leaders\hrule height\circthick\hfil\cbr
+        \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+  \ifhmode\par\fi  % can't be in the midst of a paragraph.
+  \startsavinginserts
+  \lskip=\leftskip \rskip=\rightskip
+  \leftskip=0pt\rightskip=0pt % we want these *outside*.
+  \cartinner=\hsize \advance\cartinner by-\lskip
+  \advance\cartinner by-\rskip
+  \cartouter=\hsize
+  \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+                               % side, and for 6pt waste from
+                               % each corner char, and rule thickness
+  \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+  % Flag to tell @lisp, etc., not to narrow margin.
+  \let\nonarrowing = t%
+  \vbox\bgroup
+      \baselineskip=0pt\parskip=0pt\lineskip=0pt
+      \carttop
+      \hbox\bgroup
+         \hskip\lskip
+         \vrule\kern3pt
+         \vbox\bgroup
+             \kern3pt
+             \hsize=\cartinner
+             \baselineskip=\normbskip
+             \lineskip=\normlskip
+             \parskip=\normpskip
+             \vskip -\parskip
+             \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+              \ifhmode\par\fi
+             \kern3pt
+         \egroup
+         \kern3pt\vrule
+         \hskip\rskip
+      \egroup
+      \cartbot
+  \egroup
+  \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+  \aboveenvbreak
+  \hfuzz = 12pt % Don't be fussy
+  \sepspaces % Make spaces be word-separators rather than space tokens.
+  \let\par = \lisppar % don't ignore blank lines
+  \obeylines % each line of input is a line of output
+  \parskip = 0pt
+  \parindent = 0pt
+  \emergencystretch = 0pt % don't try to avoid overfull boxes
+  \ifx\nonarrowing\relax
+    \advance \leftskip by \lispnarrowing
+    \exdentamount=\lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \let\exdent=\nofillexdent
+}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+%    @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+  \ifx\SETdispenvsize\smallword
+    \smallexamplefonts \rm
+  \fi
+}
+\def\setsmalldispenv{%
+  \ifx\SETdispenvsize\nosmallword
+  \else
+    \smallexamplefonts \rm
+  \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+  \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+  \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+  \expandafter\let\csname E#1\endcsname \afterenvbreak
+  \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+  \makedispenv{#1}{#3}
+  \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+  \nonfillstart
+  \tt
+  \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+  \gobble       % eat return
+}
+
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+  \nonfillstart
+  \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \advance\leftskip by 0pt plus 1fill
+  \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.  We keep \parskip nonzero in general, since
+% we're doing normal filling.  So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\envdef\quotation{%
+  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+  \parindent=0pt
+  %
+  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+  \ifx\nonarrowing\relax
+    \advance\leftskip by \lispnarrowing
+    \advance\rightskip by \lispnarrowing
+    \exdentamount = \lispnarrowing
+  \else
+    \let\nonarrowing = \relax
+  \fi
+  \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+  \par
+  \ifx\quotationauthor\undefined\else
+    % indent a bit.
+    \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+  \fi
+  {\parskip=0pt \afterenvbreak}%
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty \else
+    {\bf #1: }%
+  \fi
+}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command.  --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996.  The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too.  Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+  \do\ \do\\\do\{\do\}\do\$\do\&%
+  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+  \do\<\do\>\do\|\do\@\do+\do\"%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+  \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% [Knuth] pp. 380,381,391
+% Disable Spanish ligatures ?` and !` of \tt font
+\begingroup
+  \catcode`\`=\active\gdef`{\relax\lq}
+\endgroup
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+  \tt  % easiest (and conventionally used) font for verbatim
+  \def\par{\leavevmode\endgraf}%
+  \catcode`\`=\active
+  \tabeightspaces
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabexpand{%
+    \catcode`\^^I=\active
+    \def^^I{\leavevmode\egroup
+      \dimen0=\wd0 % the width so far, or since the previous tab
+      \divide\dimen0 by\tabw
+      \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+      \advance\dimen0 by\tabw  % advance to next multiple of \tabw
+      \wd0=\dimen0 \box0 \starttabbox
+    }%
+  }
+\endgroup
+\def\setupverbatim{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  % Easiest (and conventionally used) font for verbatim
+  \tt
+  \def\par{\leavevmode\egroup\box0\endgraf}%
+  \catcode`\`=\active
+  \tabexpand
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+  \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters.  Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+%    \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+  \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+  \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+%     \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+  \catcode`\ =\active
+  \obeylines %
+  % ignore everything up to the first ^^M, that's the newline at the end
+  % of the @verbatim input line itself.  Otherwise we get an extra blank
+  % line in the output.
+  \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+  % We really want {...\end verbatim} in the body of the macro, but
+  % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+    \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+  {%
+    \makevalueexpandable
+    \setupverbatim
+    \input #1
+    \afterenvbreak
+  }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+  \begingroup
+    \parindent = 0pt  % paragraph indentation looks wrong on title page
+    \scanexp\copyingtext
+  \endgroup
+}
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+% Start the processing of @deffn:
+\def\startdefun{%
+  \ifnum\lastpenalty<10000
+    \medbreak
+  \else
+    % If there are two @def commands in a row, we'll have a \nobreak,
+    % which is there to keep the function description together with its
+    % header.  But if there's nothing but headers, we need to allow a
+    % break somewhere.  Check specifically for penalty 10002, inserted
+    % by \defargscommonending, instead of 10000, since the sectioning
+    % commands also insert a nobreak penalty, and we don't want to allow
+    % a break between a section heading and a defun.
+    % 
+    \ifnum\lastpenalty=10002 \penalty2000 \fi
+    %
+    % Similarly, after a section heading, do not allow a break.
+    % But do insert the glue.
+    \medskip  % preceded by discardable penalty, so not a breakpoint
+  \fi
+  %
+  \parindent=0in
+  \advance\leftskip by \defbodyindent
+  \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+  % First, check whether we are in the right environment:
+  \checkenv#1%
+  %
+  % As above, allow line break if we have multiple x headers in a row.
+  % It's not a great place, though.
+  \ifnum\lastpenalty=10002 \penalty3000 \fi
+  %
+  % And now, it's time to reuse the body of the original defun:
+  \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+  \begingroup
+    % call \deffnheader:
+    #1#2 \endheader
+    % common ending:
+    \interlinepenalty = 10000
+    \advance\rightskip by 0pt plus 1fil
+    \endgraf
+    \nobreak\vskip -\parskip
+    \penalty 10002  % signal to \startdefun and \dodefunx
+    % Some of the @defun-type tags do not enable magic parentheses,
+    % rendering the following check redundant.  But we don't optimize.
+    \checkparencounts
+  \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remainnig is to define \deffnheader.
+%
+\def\makedefun#1{%
+  \expandafter\let\csname E#1\endcsname = \Edefun
+  \edef\temp{\noexpand\domakedefun
+    \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+  \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+  \envdef#1{%
+    \startdefun
+    \parseargusing\activeparens{\printdefunline#3}%
+  }%
+  \def#2{\dodefunx#1}%
+  \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+  % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+  \dosubind{fn}{\code{#3}}{#1}%
+  \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{fn}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{vr}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+  \doind{tp}{\code{#2}}%
+  \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+  % Get the values of \leftskip and \rightskip as they were outside the @def...
+  \advance\leftskip by -\defbodyindent
+  %
+  % How we'll format the type name.  Putting it in brackets helps
+  % distinguish it from the body text that may end up on the next line
+  % just below it.
+  \def\temp{#1}%
+  \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+  %
+  % Figure out line sizes for the paragraph shape.
+  % The first line needs space for \box0; but if \rightskip is nonzero,
+  % we need only space for the part of \box0 which exceeds it:
+  \dimen0=\hsize  \advance\dimen0 by -\wd0  \advance\dimen0 by \rightskip
+  % The continuations:
+  \dimen2=\hsize  \advance\dimen2 by -\defargsindent
+  % (plain.tex says that \dimen1 should be used only as global.)
+  \parshape 2 0in \dimen0 \defargsindent \dimen2
+  %
+  % Put the type name to the right margin.
+  \noindent
+  \hbox to 0pt{%
+    \hfil\box0 \kern-\hsize
+    % \hsize has to be shortened this way:
+    \kern\leftskip
+    % Intentionally do not respect \rightskip, since we need the space.
+  }%
+  %
+  % Allow all lines to be underfull without complaint:
+  \tolerance=10000 \hbadness=10000
+  \exdentamount=\defbodyindent
+  {%
+    % defun fonts. We use typewriter by default (used to be bold) because:
+    % . we're printing identifiers, they should be in tt in principle.
+    % . in languages with many accents, such as Czech or French, it's
+    %   common to leave accents off identifiers.  The result looks ok in
+    %   tt, but exceedingly strange in rm.
+    % . we don't want -- and --- to be treated as ligatures.
+    % . this still does not fix the ?` and !` ligatures, but so far no
+    %   one has made identifiers using them :).
+    \df \tt
+    \def\temp{#2}% return value type
+    \ifx\temp\empty\else \tclose{\temp} \fi
+    #3% output function name
+  }%
+  {\rm\enskip}% hskip 0.5 em of \tenrm
+  %
+  \boldbrax
+  % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name.  This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable.  Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+  % use sl by default (not ttsl),
+  % tt for the names.
+  \df \sl \hyphenchar\font=0
+  %
+  % On the other hand, if an argument has two dashes (for instance), we
+  % want a way to get ttsl.  Let's try @var for that.
+  \let\var=\ttslanted
+  #1%
+  \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+  \catcode`\(=\active \catcode`\)=\active
+  \catcode`\[=\active \catcode`\]=\active
+  \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc.  For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+  \activeparens
+  \global\let(=\lparen \global\let)=\rparen
+  \global\let[=\lbrack \global\let]=\rbrack
+  \global\let& = \&
+
+  \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+  \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+  \ifampseen
+    % At the first level, print parens in roman,
+    % otherwise use the default font.
+    \ifnum \parencount=1 \rm \fi
+  \else
+    % The \sf parens (in \boldbrax) actually are a little bolder than
+    % the contained text.  This is especially needed for [ and ] .
+    \sf
+  \fi
+}
+\def\infirstlevel#1{%
+  \ifampseen
+    \ifnum\parencount=1
+      #1%
+    \fi
+  \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+  \global\advance\parencount by 1
+  {\parenfont(}%
+  \infirstlevel \bfafterword
+}
+\def\clnr{%
+  {\parenfont)}%
+  \infirstlevel \sl
+  \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+  \global\advance\brackcount by 1
+  {\bf[}%
+}
+\def\rbrb{%
+  {\bf]}%
+  \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+  \ifnum\parencount=0 \else \badparencount \fi
+  \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+\def\badparencount{%
+  \errmessage{Unbalanced parentheses in @def}%
+  \global\parencount=0
+}
+\def\badbrackcount{%
+  \errmessage{Unbalanced square braces in @def}%
+  \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+  \newwrite\macscribble
+  \def\scantokens#1{%
+    \toks0={#1}%
+    \immediate\openout\macscribble=\jobname.tmp
+    \immediate\write\macscribble{\the\toks0}%
+    \immediate\closeout\macscribble
+    \input \jobname.tmp
+  }
+\fi
+
+\def\scanmacro#1{%
+  \begingroup
+    \newlinechar`\^^M
+    \let\xeatspaces\eatspaces
+    % Undo catcode changes of \startcontents and \doprintindex
+    % When called from @insertcopying or (short)caption, we need active
+    % backslash to get it printed correctly.  Previously, we had
+    % \catcode`\\=\other instead.  We'll see whether a problem appears
+    % with macro expansion.                            --kasal, 19aug04
+    \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+    % ... and \example
+    \spaceisspace
+    %
+    % Append \endinput to make sure that TeX does not see the ending newline.
+    %
+    % I've verified that it is necessary both for e-TeX and for ordinary TeX
+    %                                                  --kasal, 29nov03
+    \scantokens{#1\endinput}%
+  \endgroup
+}
+
+\def\scanexp#1{%
+  \edef\temp{\noexpand\scanmacro{#1}}%
+  \temp
+}
+
+\newcount\paramno   % Count of parameters
+\newtoks\macname    % Macro name
+\newif\ifrecursive  % Is it recursive?
+
+% List of all defined macros in the form
+%    \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+     \toks0 = \expandafter{\macrolist\definedummyword#1}%
+     \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+%   \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+% 
+\def\cslet#1#2{%
+  \expandafter\let
+  \csname#1\expandafter\endcsname
+  \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by  making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\scanctxt{%
+  \catcode`\"=\other
+  \catcode`\+=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\@=\other
+  \catcode`\^=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\~=\other
+}
+
+\def\scanargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+  \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+  \scanctxt
+  \catcode`\{=\other
+  \catcode`\}=\other
+  \catcode`\^^M=\other
+  \usembodybackslash
+}
+
+\def\macroargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+  \getargs{#1}%           now \macname is the macname and \argl the arglist
+  \ifx\argl\empty       % no arguments
+     \paramno=0%
+  \else
+     \expandafter\parsemargdef \argl;%
+  \fi
+  \if1\csname ismacro.\the\macname\endcsname
+     \message{Warning: redefining \the\macname}%
+  \else
+     \expandafter\ifx\csname \the\macname\endcsname \relax
+     \else \errmessage{Macro name \the\macname\space already defined}\fi
+     \global\cslet{macsave.\the\macname}{\the\macname}%
+     \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+     \addtomacrolist{\the\macname}%
+  \fi
+  \begingroup \macrobodyctxt
+  \ifrecursive \expandafter\parsermacbody
+  \else \expandafter\parsemacbody
+  \fi}
+
+\parseargdef\unmacro{%
+  \if1\csname ismacro.#1\endcsname
+    \global\cslet{#1}{macsave.#1}%
+    \global\expandafter\let \csname ismacro.#1\endcsname=0%
+    % Remove the macro name from \macrolist:
+    \begingroup
+      \expandafter\let\csname#1\endcsname \relax
+      \let\definedummyword\unmacrodo
+      \xdef\macrolist{\macrolist}%
+    \endgroup
+  \else
+    \errmessage{Macro #1 not defined}%
+  \fi
+}
+
+% Called by \do from \dounmacro on each macro.  The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+  \ifx #1\relax
+    % remove this
+  \else
+    \noexpand\definedummyword \noexpand#1%
+  \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list.  Set up \paramno and \paramlist
+% so \defmacro knows what to do.  Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX:  let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+        \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+  \if#1;\let\next=\relax
+  \else \let\next=\parsemargdefxxx
+    \advance\paramno by 1%
+    \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+        {\xeatspaces{\hash\the\paramno}}%
+    \edef\paramlist{\paramlist\hash\the\paramno,}%
+  \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+  \let\hash=##% convert placeholders to macro parameter chars
+  \ifrecursive
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\scanmacro{\temp}}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+         \egroup\noexpand\scanmacro{\temp}}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+        \csname\the\macname xxx\endcsname
+          \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+    \fi
+  \else
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+        \egroup
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \expandafter\noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+      \csname\the\macname xxx\endcsname
+      \paramlist{%
+          \egroup
+          \noexpand\norecurse{\the\macname}%
+          \noexpand\scanmacro{\temp}\egroup}%
+    \fi
+  \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {.  If so it reads up to the closing }, if not, it reads the whole
+% line.  Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+  \ifx\nchar\bgroup\else
+    \expandafter\parsearg
+  \fi \next}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign.  Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+  {%
+    \expandafter\let\obeyedspace=\empty
+    \addtomacrolist{#1}%
+    \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+  }%
+  \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+
+\newif\ifhavexrefs    % True if xref values are known.
+\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+  node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references.  The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross,  ,  , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node.  #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+  \ifx\lastnode\empty\else
+    \setref{\lastnode}{#1}%
+    \global\let\lastnode=\empty
+  \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \thissection,
+%                 or the anchor name.
+% 2) NAME-snt   - section number and type, passed as the SNT arg, or
+%                 empty for anchors.
+% 3) NAME-pg    - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat.  In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof   - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+  \pdfmkdest{#1}%
+  \iflinks
+    {%
+      \atdummies  % preserve commands, but don't expand them
+      \edef\writexrdef##1##2{%
+       \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+         ##1}{##2}}% these are parameters of \writexrdef
+      }%
+      \toks0 = \expandafter{\thissection}%
+      \immediate \writexrdef{title}{\the\toks0 }%
+      \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+      \writexrdef{pg}{\folio}% will be written later, during \shipout
+    }%
+  \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual.  All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+  \unsepspaces
+  \def\printedmanual{\ignorespaces #5}%
+  \def\printedrefname{\ignorespaces #3}%
+  \setbox1=\hbox{\printedmanual\unskip}%
+  \setbox0=\hbox{\printedrefname\unskip}%
+  \ifdim \wd0 = 0pt
+    % No printed node name was explicitly given.
+    \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+      % Use the node name inside the square brackets.
+      \def\printedrefname{\ignorespaces #1}%
+    \else
+      % Use the actual chapter/section title appear inside
+      % the square brackets.  Use the real section title if we have it.
+      \ifdim \wd1 > 0pt
+        % It is in another manual, so we don't have it.
+        \def\printedrefname{\ignorespaces #1}%
+      \else
+        \ifhavexrefs
+          % We know the real title if we have the xref values.
+          \def\printedrefname{\refx{#1-title}{}}%
+        \else
+          % Otherwise just copy the Info node name.
+          \def\printedrefname{\ignorespaces #1}%
+        \fi%
+      \fi
+    \fi
+  \fi
+  %
+  % Make link in pdf output.
+  \ifpdf
+    \leavevmode
+    \getfilename{#4}%
+    {\turnoffactive
+     % See comments at \activebackslashdouble.
+     {\activebackslashdouble \xdef\pdfxrefdest{#1}%
+      \backslashparens\pdfxrefdest}%
+     %
+     \ifnum\filenamelength>0
+       \startlink attr{/Border [0 0 0]}%
+         goto file{\the\filename.pdf} name{\pdfxrefdest}%
+     \else
+       \startlink attr{/Border [0 0 0]}%
+         goto name{\pdfmkpgn{\pdfxrefdest}}%
+     \fi
+    }%
+    \linkcolor
+  \fi
+  %
+  % Float references are printed completely differently: "Figure 1.2"
+  % instead of "[somenode], p.3".  We distinguish them by the
+  % LABEL-title being set to a magic string.
+  {%
+    % Have to otherify everything special to allow the \csname to
+    % include an _ in the xref name, etc.
+    \indexnofonts
+    \turnoffactive
+    \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+      \csname XR#1-title\endcsname
+  }%
+  \iffloat\Xthisreftitle
+    % If the user specified the print name (third arg) to the ref,
+    % print it instead of our usual "Figure 1.2".
+    \ifdim\wd0 = 0pt
+      \refx{#1-snt}%
+    \else
+      \printedrefname
+    \fi
+    %
+    % if the user also gave the printed manual name (fifth arg), append
+    % "in MANUALNAME".
+    \ifdim \wd1 > 0pt
+      \space \putwordin{} \cite{\printedmanual}%
+    \fi
+  \else
+    % node/anchor (non-float) references.
+    %
+    % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+    % insert empty discretionaries after hyphens, which means that it will
+    % not find a line break at a hyphen in a node names.  Since some manuals
+    % are best written with fairly long node names, containing hyphens, this
+    % is a loss.  Therefore, we give the text of the node name again, so it
+    % is as if TeX is seeing it for the first time.
+    \ifdim \wd1 > 0pt
+      \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+    \else
+      % _ (for example) has to be the character _ for the purposes of the
+      % control sequence corresponding to the node, but it has to expand
+      % into the usual \leavevmode...\vrule stuff for purposes of
+      % printing. So we \turnoffactive for the \refx-snt, back on for the
+      % printing, back off for the \refx-pg.
+      {\turnoffactive
+       % Only output a following space if the -snt ref is nonempty; for
+       % @unnumbered and @anchor, it won't be.
+       \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+       \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+      }%
+      % output the `[mynode]' via a macro so it can be overridden.
+      \xrefprintnodename\printedrefname
+      %
+      % But we always want a comma and a space:
+      ,\space
+      %
+      % output the `page 3'.
+      \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output.  It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents.  Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+  \ifnum\secno=0
+    \putwordChapter@tie \the\chapno
+  \else \ifnum\subsecno=0
+    \putwordSection@tie \the\chapno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+  \else
+    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+\def\Yappendix{%
+  \ifnum\secno=0
+     \putwordAppendix@tie @char\the\appendixno{}%
+  \else \ifnum\subsecno=0
+     \putwordSection@tie @char\the\appendixno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+  \else
+    \putwordSection@tie
+      @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+  {%
+    \indexnofonts
+    \otherbackslash
+    \expandafter\global\expandafter\let\expandafter\thisrefX
+      \csname XR#1\endcsname
+  }%
+  \ifx\thisrefX\relax
+    % If not defined, say something at least.
+    \angleleft un\-de\-fined\angleright
+    \iflinks
+      \ifhavexrefs
+        \message{\linenumber Undefined cross reference `#1'.}%
+      \else
+        \ifwarnedxrefs\else
+          \global\warnedxrefstrue
+          \message{Cross reference values unknown; you must run TeX again.}%
+        \fi
+      \fi
+    \fi
+  \else
+    % It's defined, so just use it.
+    \thisrefX
+  \fi
+  #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file.  Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions).  But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+  \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value.
+  %
+  % Was that xref control sequence that we just defined for a float?
+  \expandafter\iffloat\csname XR#1\endcsname
+    % it was a float, and we have the (safe) float type in \iffloattype.
+    \expandafter\let\expandafter\floatlist
+      \csname floatlist\iffloattype\endcsname
+    %
+    % Is this the first time we've seen this float type?
+    \expandafter\ifx\floatlist\relax
+      \toks0 = {\do}% yes, so just \do
+    \else
+      % had it before, so preserve previous elements in list.
+      \toks0 = \expandafter{\floatlist\do}%
+    \fi
+    %
+    % Remember this xref in the control sequence \floatlistFLOATTYPE,
+    % for later use in \listoffloats.
+    \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}%
+  \fi
+}
+
+% Read the last existing aux file, if any.  No error if none exists.
+%
+\def\tryauxfile{%
+  \openin 1 \jobname.aux
+  \ifeof 1 \else
+    \readdatafile{aux}%
+    \global\havexrefstrue
+  \fi
+  \closein 1
+}
+
+\def\setupdatafile{%
+  \catcode`\^^@=\other
+  \catcode`\^^A=\other
+  \catcode`\^^B=\other
+  \catcode`\^^C=\other
+  \catcode`\^^D=\other
+  \catcode`\^^E=\other
+  \catcode`\^^F=\other
+  \catcode`\^^G=\other
+  \catcode`\^^H=\other
+  \catcode`\^^K=\other
+  \catcode`\^^L=\other
+  \catcode`\^^N=\other
+  \catcode`\^^P=\other
+  \catcode`\^^Q=\other
+  \catcode`\^^R=\other
+  \catcode`\^^S=\other
+  \catcode`\^^T=\other
+  \catcode`\^^U=\other
+  \catcode`\^^V=\other
+  \catcode`\^^W=\other
+  \catcode`\^^X=\other
+  \catcode`\^^Z=\other
+  \catcode`\^^[=\other
+  \catcode`\^^\=\other
+  \catcode`\^^]=\other
+  \catcode`\^^^=\other
+  \catcode`\^^_=\other
+  % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+  % in xref tags, i.e., node names.  But since ^^e4 notation isn't
+  % supported in the main text, it doesn't seem desirable.  Furthermore,
+  % that is not enough: for node names that actually contain a ^
+  % character, we would end up writing a line like this: 'xrdef {'hat
+  % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+  % argument, and \hat is not an expandable control sequence.  It could
+  % all be worked out, but why?  Either we support ^^ or we don't.
+  %
+  % The other change necessary for this was to define \auxhat:
+  % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+  % and then to call \auxhat in \setq.
+  %
+  \catcode`\^=\other
+  %
+  % Special characters.  Should be turned off anyway, but...
+  \catcode`\~=\other
+  \catcode`\[=\other
+  \catcode`\]=\other
+  \catcode`\"=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\$=\other
+  \catcode`\#=\other
+  \catcode`\&=\other
+  \catcode`\%=\other
+  \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+  %
+  % This is to support \ in node names and titles, since the \
+  % characters end up in a \csname.  It's easier than
+  % leaving it active and making its active definition an actual \
+  % character.  What I don't understand is why it works in the *value*
+  % of the xrdef.  Seems like it should be a catcode12 \, and that
+  % should not typeset properly.  But it works, so I'm moving on for
+  % now.  --karl, 15jan04.
+  \catcode`\\=\other
+  %
+  % Make the characters 128-255 be printing characters.
+  {%
+    \count1=128
+    \def\loop{%
+      \catcode\count1=\other
+      \advance\count1 by 1
+      \ifnum \count1<256 \loop \fi
+    }%
+  }%
+  %
+  % @ is our escape character in .aux files, and we need braces.
+  \catcode`\{=1
+  \catcode`\}=2
+  \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+  \setupdatafile
+  \input\jobname.#1
+\endgroup}
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes.  Otherwise like plain.
+\gdef\footnote{%
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \global\advance\footnoteno by \@ne
+  \edef\thisfootno{$^{\the\footnoteno}$}%
+  %
+  % In case the footnote comes at the end of a sentence, preserve the
+  % extra spacing after we do the footnote number.
+  \let\@sf\empty
+  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+  %
+  % Remove inadvertent blank space before typesetting the footnote number.
+  \unskip
+  \thisfootno\@sf
+  \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter.  Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read.  --karl, 16nov96.
+%
+\gdef\dofootnote{%
+  \insert\footins\bgroup
+  % We want to typeset this text as a normal paragraph, even if the
+  % footnote reference occurs in (for example) a display environment.
+  % So reset some parameters.
+  \hsize=\pagewidth
+  \interlinepenalty\interfootnotelinepenalty
+  \splittopskip\ht\strutbox % top baseline for broken footnotes
+  \splitmaxdepth\dp\strutbox
+  \floatingpenalty\@MM
+  \leftskip\z@skip
+  \rightskip\z@skip
+  \spaceskip\z@skip
+  \xspaceskip\z@skip
+  \parindent\defaultparindent
+  %
+  \smallfonts \rm
+  %
+  % Because we use hanging indentation in footnotes, a @noindent appears
+  % to exdent this text, so make it be a no-op.  makeinfo does not use
+  % hanging indentation so @noindent can still be needed within footnote
+  % text after an @example or the like (not that this is good style).
+  \let\noindent = \relax
+  %
+  % Hang the footnote text off the number.  Use \everypar in case the
+  % footnote extends for more than one paragraph.
+  \everypar = {\hang}%
+  \textindent{\thisfootno}%
+  %
+  % Don't crash into the line above the footnote text.  Since this
+  % expands into a box, it must come within the paragraph, lest it
+  % provide a place where TeX can split the footnote.
+  \footstrut
+  \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished.  Otherwise, the insertion
+% would be lost.
+% Similarily, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes.  --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+  \ifx \insert\ptexinsert
+    \let\insert\saveinsert
+  \else
+    \let\checkinserts\relax
+  \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+  \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+  \afterassignment\next
+  % swallow the left brace
+  \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+  \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+    {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+  \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials  %  ;-)
+  \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+  \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+  \next
+}
+\def\newsaveinsX #1{%
+  \csname newbox\endcsname #1%
+  \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+    \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image.  We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front.  If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+  % Do not bother showing banner with epsf.tex v2.7k (available in
+  % doc/epsf.tex and on ctan).
+  \def\epsfannounce{\toks0 = }%
+  \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+  work.  It is also included in the Texinfo distribution, or you can get
+  it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+  \ifx\epsfbox\undefined
+    \ifwarnednoepsf \else
+      \errhelp = \noepsfhelp
+      \errmessage{epsf.tex not found, images will be ignored}%
+      \global\warnednoepsftrue
+    \fi
+  \else
+    \imagexxx #1,,,,,\finish
+  \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+  \catcode`\^^M = 5     % in case we're inside an example
+  \normalturnoffactive  % allow _ et al. in names
+  % If the image is by itself, center it.
+  \ifvmode
+    \imagevmodetrue
+    \nobreak\bigskip
+    % Usually we'll have text after the image which will insert
+    % \parskip glue, so insert it here too to equalize the space
+    % above and below.
+    \nobreak\vskip\parskip
+    \nobreak
+    \line\bgroup\hss
+  \fi
+  %
+  % Output the image.
+  \ifpdf
+    \dopdfimage{#1}{#2}{#3}%
+  \else
+    % \epsfbox itself resets \epsf?size at each figure.
+    \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+    \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+    \epsfbox{#1.eps}%
+  \fi
+  %
+  \ifimagevmode \hss \egroup \bigbreak \fi  % space after the image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc.  We don't actually implement floating yet, we always include the
+% float "here".  But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc.  Can't contain commas.  If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label.  Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored.  It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+  \let\thiscaption=\empty
+  \let\thisshortcaption=\empty
+  %
+  % don't lose footnotes inside @float.
+  %
+  % BEWARE: when the floats start float, we have to issue warning whenever an
+  % insert appears inside a float which could possibly float. --kasal, 26may04
+  %
+  \startsavinginserts
+  %
+  % We can't be used inside a paragraph.
+  \par
+  %
+  \vtop\bgroup
+    \def\floattype{#1}%
+    \def\floatlabel{#2}%
+    \def\floatloc{#3}% we do nothing with this yet.
+    %
+    \ifx\floattype\empty
+      \let\safefloattype=\empty
+    \else
+      {%
+        % the floattype might have accents or other special characters,
+        % but we need to use it in a control sequence name.
+        \indexnofonts
+        \turnoffactive
+        \xdef\safefloattype{\floattype}%
+      }%
+    \fi
+    %
+    % If label is given but no type, we handle that as the empty type.
+    \ifx\floatlabel\empty \else
+      % We want each FLOATTYPE to be numbered separately (Figure 1,
+      % Table 1, Figure 2, ...).  (And if no label, no number.)
+      %
+      \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+      \global\advance\floatno by 1
+      %
+      {%
+        % This magic value for \thissection is output by \setref as the
+        % XREFLABEL-title value.  \xrefX uses it to distinguish float
+        % labels (which have a completely different output format) from
+        % node and anchor labels.  And \xrdef uses it to construct the
+        % lists of floats.
+        %
+        \edef\thissection{\floatmagic=\safefloattype}%
+        \setref{\floatlabel}{Yfloat}%
+      }%
+    \fi
+    %
+    % start with \parskip glue, I guess.
+    \vskip\parskip
+    %
+    % Don't suppress indentation if a float happens to start a section.
+    \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption:    Foo 1.1
+% @float Foo & @caption{Cap}:     Foo: Cap
+% @float Foo & no caption:        Foo
+% @float ,lbl & Caption{Cap}:     1.1: Cap
+% @float ,lbl & no caption:       1.1
+% @float & @caption{Cap}:         Cap
+% @float & no caption:
+%
+\def\Efloat{%
+    \let\floatident = \empty
+    %
+    % In all cases, if we have a float type, it comes first.
+    \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+    %
+    % If we have an xref label, the number comes next.
+    \ifx\floatlabel\empty \else
+      \ifx\floattype\empty \else % if also had float type, need tie first.
+        \appendtomacro\floatident{\tie}%
+      \fi
+      % the number.
+      \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+    \fi
+    %
+    % Start the printed caption with what we've constructed in
+    % \floatident, but keep it separate; we need \floatident again.
+    \let\captionline = \floatident
+    %
+    \ifx\thiscaption\empty \else
+      \ifx\floatident\empty \else
+       \appendtomacro\captionline{: }% had ident, so need a colon between
+      \fi
+      %
+      % caption text.
+      \appendtomacro\captionline{\scanexp\thiscaption}%
+    \fi
+    %
+    % If we have anything to print, print it, with space before.
+    % Eventually this needs to become an \insert.
+    \ifx\captionline\empty \else
+      \vskip.5\parskip
+      \captionline
+      %
+      % Space below caption.
+      \vskip\parskip
+    \fi
+    %
+    % If have an xref label, write the list of floats info.  Do this
+    % after the caption, to avoid chance of it being a breakpoint.
+    \ifx\floatlabel\empty \else
+      % Write the text that goes in the lof to the aux file as
+      % \floatlabel-lof.  Besides \floatident, we include the short
+      % caption if specified, else the full caption if specified, else nothing.
+      {%
+        \atdummies
+        % since we read the caption text in the macro world, where ^^M
+        % is turned into a normal character, we have to scan it back, so
+        % we don't write the literal three characters "^^M" into the aux file.
+       \scanexp{%
+         \xdef\noexpand\gtemp{%
+           \ifx\thisshortcaption\empty
+             \thiscaption
+           \else
+             \thisshortcaption
+           \fi
+         }%
+       }%
+        \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+         \ifx\gtemp\empty \else : \gtemp \fi}}%
+      }%
+    \fi
+  \egroup  % end of \vtop
+  %
+  % place the captured inserts
+  %
+  % BEWARE: when the floats start float, we have to issue warning whenever an
+  % insert appears inside a float which could possibly float. --kasal, 26may04
+  %
+  \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+  \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use.  Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+  \ifx#1\relax
+      % Haven't seen this figure type before.
+      \csname newcount\endcsname #1%
+      %
+      % Remember to reset this floatno at the next chap.
+      \expandafter\gdef\expandafter\resetallfloatnos
+        \expandafter{\resetallfloatnos #1=0 }%
+  \fi
+  \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value.  We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1".  We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref.  That is, the magic
+% \thissection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string.  If so, #2 will be the
+% (safe) float type for this float.  We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+  \def\temp{#1}%
+  \def\iffloattype{#2}%
+  \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+  \def\floattype{#1}% floattype
+  {%
+    % the floattype might have accents or other special characters,
+    % but we need to use it in a control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safefloattype{\floattype}%
+  }%
+  %
+  % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+  \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+    \ifhavexrefs
+      % if the user said @listoffloats foo but never @float foo.
+      \message{\linenumber No `\safefloattype' floats to list.}%
+    \fi
+  \else
+    \begingroup
+      \leftskip=\tocindent  % indent these entries like a toc
+      \let\do=\listoffloatsdo
+      \csname floatlist\safefloattype\endcsname
+    \endgroup
+  \fi
+}
+
+% This is called on each entry in a list of floats.  We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file.  We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+  % Can't fully expand XR#1-lof because it can contain anything.  Just
+  % pass the control sequence.  On the other hand, XR#1-pg is just the
+  % page number, and we want to fully expand that so we can get a link
+  % in pdf output.
+  \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+  %
+  % use the same \entry macro we use to generate the TOC and index.
+  \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+  \writeentry
+}}
+
+\message{localization,}
+% and i18n.
+
+% @documentlanguage is usually given very early, just after
+% @setfilename.  If done too late, it may not override everything
+% properly.  Single argument is the language abbreviation.
+% It would be nice if we could set up a hyphenation file here.
+%
+\parseargdef\documentlanguage{%
+  \tex % read txi-??.tex file in plain TeX.
+    % Read the file if it exists.
+    \openin 1 txi-#1.tex
+    \ifeof 1
+      \errhelp = \nolanghelp
+      \errmessage{Cannot read language file txi-#1.tex}%
+    \else
+      \input txi-#1.tex
+    \fi
+    \closein 1
+  \endgroup
+}
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty.  Maybe you need to install it?  In the current directory
+should work if nowhere else does.}
+
+
+% @documentencoding should change something in TeX eventually, most
+% likely, but for now just recognize it.
+\let\documentencoding = \comment
+
+
+% Page size parameters.
+%
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything.  We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize.  We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+  \ifx\emergencystretch\thisisundefined
+    % Allow us to assign to \emergencystretch anyway.
+    \def\emergencystretch{\dimen0}%
+  \else
+    \emergencystretch = .15\hsize
+  \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading.  The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+  \voffset = #3\relax
+  \topskip = #6\relax
+  \splittopskip = \topskip
+  %
+  \vsize = #1\relax
+  \advance\vsize by \topskip
+  \outervsize = \vsize
+  \advance\outervsize by 2\topandbottommargin
+  \pageheight = \vsize
+  %
+  \hsize = #2\relax
+  \outerhsize = \hsize
+  \advance\outerhsize by 0.5in
+  \pagewidth = \hsize
+  %
+  \normaloffset = #4\relax
+  \bindingoffset = #5\relax
+  %
+  \ifpdf
+    \pdfpageheight #7\relax
+    \pdfpagewidth #8\relax
+  \fi
+  %
+  \setleading{\textleading}
+  %
+  \parindent = \defaultparindent
+  \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % If page is nothing but text, make it come out even.
+  \internalpagesizes{46\baselineskip}{6in}%
+                    {\voffset}{.25in}%
+                    {\bindingoffset}{36pt}%
+                    {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+  \parskip = 2pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.5in}{5in}%
+                    {\voffset}{.25in}%
+                    {\bindingoffset}{16pt}%
+                    {9.25in}{7in}%
+  %
+  \lispnarrowing = 0.3in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+  \parskip = 1.5pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.4in}{4.8in}%
+                    {-.2in}{-.4in}%
+                    {0pt}{14pt}%
+                    {9in}{6in}%
+  %
+  \lispnarrowing = 0.25in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % Double-side printing via postscript on Laserjet 4050
+  % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+  % To change the settings for a different printer or situation, adjust
+  % \normaloffset until the front-side and back-side texts align.  Then
+  % do the same for \bindingoffset.  You can set these for testing in
+  % your texinfo source file like this:
+  % @tex
+  % \global\normaloffset = -6mm
+  % \global\bindingoffset = 10mm
+  % @end tex
+  \internalpagesizes{51\baselineskip}{160mm}
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{44pt}%
+                    {297mm}{210mm}%
+  %
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+  \parskip = 2pt plus 1pt minus 0.1pt
+  \textleading = 12.5pt
+  %
+  \internalpagesizes{160mm}{120mm}%
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{8pt}%
+                    {210mm}{148mm}%
+  %
+  \lispnarrowing = 0.2in
+  \tolerance = 800
+  \hfuzz = 1.2pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 2mm
+  \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{237mm}{150mm}%
+                    {\voffset}{4.6mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  %
+  % Must explicitly reset to 0 because we call \afourpaper.
+  \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{241mm}{165mm}%
+                    {\voffset}{-2.95mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+  \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+  \globaldefs = 1
+  %
+  \parskip = 3pt plus 2pt minus 1pt
+  \setleading{\textleading}%
+  %
+  \dimen0 = #1
+  \advance\dimen0 by \voffset
+  %
+  \dimen2 = \hsize
+  \advance\dimen2 by \normaloffset
+  %
+  \internalpagesizes{#1}{\hsize}%
+                    {\voffset}{\normaloffset}%
+                    {\bindingoffset}{44pt}%
+                    {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise.  Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font.  Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts.  But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont  % let existing .??s files work
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+{\catcode`\\=\active
+ @gdef@rawbackslash{@let\=@backslashcurfont}
+ @gdef@otherbackslash{@let\=@realbackslash}
+}
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\backslashcurfont}}
+
+\catcode`\\=\active
+
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
+@def@turnoffactive{%
+  @let"=@normaldoublequote
+  @let\=@realbackslash
+  @let~=@normaltilde
+  @let^=@normalcaret
+  @let_=@normalunderscore
+  @let|=@normalverticalbar
+  @let<=@normalless
+  @let>=@normalgreater
+  @let+=@normalplus
+  @let$=@normaldollar %$ font-lock fix
+  @unsepspaces
+}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.  (Thus, \ is not expandable when this is in
+% effect.)
+%
+@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\{ in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+  @ifx\@eatinput @let\ = @normalbackslash @fi
+  @catcode`+=@active
+  @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+@catcode`@& = @other
+@catcode`@# = @other
+@catcode`@% = @other
+
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+   arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/h/getopt.h b/h/getopt.h
new file mode 100644 (file)
index 0000000..cc45f46
--- /dev/null
@@ -0,0 +1,169 @@
+/* Declarations for getopt.
+
+   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
+   1999, 2001, 2003 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.  */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+   standalone, or this is the first header included in the source file.
+   If we are being used with glibc, we need to include <features.h>, but
+   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
+   not defined, include <ctype.h>, which will pull in <features.h> for us
+   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
+   doesn't flood the namespace with stuff the way some other headers do.)  */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 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.  */
+
+extern 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 -1, 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.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument         (or 0) if the option does not take an argument,
+   required_argument   (or 1) if the option requires an argument,
+   optional_argument   (or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+  const char *name;
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+# define no_argument           0
+# define required_argument     1
+# define optional_argument     2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+   arguments in ARGV (ARGC of them, minus the program name) for
+   options given in OPTS.
+
+   Return the option character from OPTS just read.  Return -1 when
+   there are no more options.  For unrecognized options, or options
+   missing arguments, `optopt' is set to the option letter, and '?' is
+   returned.
+
+   The OPTS string is a list of characters which are recognized option
+   letters, optionally followed by colons, specifying that that letter
+   takes an argument, to be placed in `optarg'.
+
+   If a letter in OPTS is followed by two colons, its argument is
+   optional.  This behavior is specific to the GNU `getopt'.
+
+   The argument `--' causes premature termination of argument
+   scanning, explicitly telling `getopt' that there are no more
+   options.
+
+   If OPTS begins with `--', then non-option arguments are treated as
+   arguments to the option '\0'.  This behavior is specific to the GNU
+   `getopt'.  */
+
+#ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* __GNU_LIBRARY__ */
+
+#ifndef __need_getopt
+extern int getopt_long (int ___argc, char *const *___argv,
+                       const char *__shortopts,
+                       const struct option *__longopts, int *__longind);
+extern int getopt_long_only (int ___argc, char *const *___argv,
+                            const char *__shortopts,
+                            const struct option *__longopts, int *__longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int ___argc, char *const *___argv,
+                            const char *__shortopts,
+                            const struct option *__longopts, int *__longind,
+                            int __long_only);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations.  */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/h/number.h b/h/number.h
new file mode 100644 (file)
index 0000000..9b034b6
--- /dev/null
@@ -0,0 +1,153 @@
+/* number.h: Arbitrary precision numbers header file. */
+/*
+    Copyright (C) 1991, 1992, 1993, 1994, 1997, 2000 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+
+      The Free Software Foundation, Inc.
+      51 Franklin Street, Fifth Floor
+      Boston, MA 02110-1301  USA
+
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+#ifndef _NUMBER_H_
+#define _NUMBER_H_
+
+typedef enum {PLUS, MINUS} sign;
+
+typedef struct bc_struct *bc_num;
+
+typedef struct bc_struct
+    {
+      sign  n_sign;
+      int   n_len;     /* The number of digits before the decimal point. */
+      int   n_scale;   /* The number of digits after the decimal point. */
+      int   n_refs;     /* The number of pointers to this number. */
+      bc_num n_next;   /* Linked list for available list. */
+      char *n_ptr;     /* The pointer to the actual storage.
+                          If NULL, n_value points to the inside of
+                          another number (bc_multiply...) and should
+                          not be "freed." */
+      char *n_value;   /* The number. Not zero char terminated.
+                          May not point to the same place as n_ptr as
+                          in the case of leading zeros generated. */
+    } bc_struct;
+
+
+/* The base used in storing the numbers in n_value above.
+   Currently this MUST be 10. */
+
+#define BASE 10
+
+/*  Some useful macros and constants. */
+
+#define CH_VAL(c)     (c - '0')
+#define BCD_CHAR(d)   (d + '0')
+
+#ifdef MIN
+#undef MIN
+#undef MAX
+#endif
+#define MAX(a,b)      ((a)>(b)?(a):(b))
+#define MIN(a,b)      ((a)>(b)?(b):(a))
+#define ODD(a)        ((a)&1)
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 0x7fffffff
+#endif
+
+
+/* Global numbers. */
+extern bc_num _zero_;
+extern bc_num _one_;
+extern bc_num _two_;
+
+
+/* Function Prototypes */
+
+/* Define the _PROTOTYPE macro if it is needed. */
+
+#ifndef _PROTOTYPE
+#ifdef __STDC__
+#define _PROTOTYPE(func, args) func args
+#else
+#define _PROTOTYPE(func, args) func()
+#endif
+#endif
+
+_PROTOTYPE(void bc_init_numbers, (void));
+
+_PROTOTYPE(bc_num bc_new_num, (int length, int scale));
+
+_PROTOTYPE(void bc_free_num, (bc_num *num));
+
+_PROTOTYPE(bc_num bc_copy_num, (bc_num num));
+
+_PROTOTYPE(void bc_init_num, (bc_num *num));
+
+_PROTOTYPE(void bc_str2num, (bc_num *num, char *str, int scale));
+
+_PROTOTYPE(char *bc_num2str, (bc_num num));
+
+_PROTOTYPE(void bc_int2num, (bc_num *num, int val));
+
+_PROTOTYPE(long bc_num2long, (bc_num num));
+
+_PROTOTYPE(int bc_compare, (bc_num n1, bc_num n2));
+
+_PROTOTYPE(char bc_is_zero, (bc_num num));
+
+_PROTOTYPE(char bc_is_near_zero, (bc_num num, int scale));
+
+_PROTOTYPE(char bc_is_neg, (bc_num num));
+
+_PROTOTYPE(void bc_add, (bc_num n1, bc_num n2, bc_num *result, int scale_min));
+
+_PROTOTYPE(void bc_sub, (bc_num n1, bc_num n2, bc_num *result, int scale_min));
+
+_PROTOTYPE(void bc_multiply, (bc_num n1, bc_num n2, bc_num *prod, int scale));
+
+_PROTOTYPE(int bc_divide, (bc_num n1, bc_num n2, bc_num *quot, int scale));
+
+_PROTOTYPE(int bc_modulo, (bc_num num1, bc_num num2, bc_num *result,
+                          int scale));
+
+_PROTOTYPE(int bc_divmod, (bc_num num1, bc_num num2, bc_num *quot,
+                          bc_num *rem, int scale));
+
+_PROTOTYPE(int bc_raisemod, (bc_num base, bc_num expo, bc_num mod,
+                            bc_num *result, int scale));
+
+_PROTOTYPE(void bc_raise, (bc_num num1, bc_num num2, bc_num *result,
+                          int scale));
+
+_PROTOTYPE(int bc_sqrt, (bc_num *num, int scale));
+
+_PROTOTYPE(void bc_out_num, (bc_num num, int o_base, void (* out_char)(int),
+                            int leading_zero));
+
+#endif
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..4d4a951
--- /dev/null
@@ -0,0 +1,323 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2005-05-14.22
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -c) shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t) dstarg=$2
+       shift
+       shift
+       continue;;
+
+    -T) no_target_directory=true
+       shift
+       continue;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    *)  # When -d is used, all remaining arguments are directories to create.
+       # When -t is used, the destination is already specified.
+       test -n "$dir_arg$dstarg" && break
+        # Otherwise, the last argument is the destination.  Remove it from $@.
+       for arg
+       do
+          if test -n "$dstarg"; then
+           # $@ is not empty: it contains at least $arg.
+           set fnord "$@" "$dstarg"
+           shift # fnord
+         fi
+         shift # arg
+         dstarg=$arg
+       done
+       break;;
+  esac
+done
+
+if test -z "$1"; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    src=
+
+    if test -d "$dst"; then
+      mkdircmd=:
+      chmodcmd=
+    else
+      mkdircmd=$mkdirprog
+    fi
+  else
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+       echo "$0: $dstarg: Is a directory" >&2
+       exit 1
+      fi
+      dst=$dst/`basename "$src"`
+    fi
+  fi
+
+  # This sed command emulates the dirname command.
+  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
+
+  # Make sure that the destination directory exists.
+
+  # Skip lots of stat calls in the usual case.
+  if test ! -d "$dstdir"; then
+    defaultIFS='
+        '
+    IFS="${IFS-$defaultIFS}"
+
+    oIFS=$IFS
+    # Some sh's can't handle IFS=/ for some reason.
+    IFS='%'
+    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+    shift
+    IFS=$oIFS
+
+    pathcomp=
+
+    while test $# -ne 0 ; do
+      pathcomp=$pathcomp$1
+      shift
+      if test ! -d "$pathcomp"; then
+        $mkdirprog "$pathcomp"
+       # mkdir can fail with a `File exist' error in case several
+       # install-sh are creating the directory concurrently.  This
+       # is OK.
+       test -d "$pathcomp" || exit
+      fi
+      pathcomp=$pathcomp/
+    done
+  fi
+
+  if test -n "$dir_arg"; then
+    $doit $mkdircmd "$dst" \
+      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+  else
+    dstfile=`basename "$dst"`
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+    trap '(exit $?); exit' 1 2 13 15
+
+    # Copy the file name to the temp name.
+    $doit $cpprog "$src" "$dsttmp" &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+      || {
+          # The rename failed, perhaps because mv can't rename something else
+          # to itself, or perhaps because mv is so ancient that it does not
+          # support -f.
+
+          # Now remove or move aside any old file at destination location.
+          # We try this two ways since rm can't unlink itself on some
+          # systems and the destination file might be busy for other
+          # reasons.  In this case, the final cleanup might fail but the new
+          # file should still install successfully.
+          {
+            if test -f "$dstdir/$dstfile"; then
+              $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+              || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+              || {
+                echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+                (exit 1); exit 1
+              }
+            else
+              :
+            fi
+          } &&
+
+          # Now rename the file to the real destination.
+          $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+        }
+    }
+  fi || { (exit 1); exit 1; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit 0
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644 (file)
index 0000000..70cd43b
--- /dev/null
@@ -0,0 +1,26 @@
+## Process this file with automake to produce Makefile.in
+noinst_LIBRARIES = libbc.a
+
+INCLUDES = -I. -I.. -I$(srcdir)/../h
+
+libbc_a_SOURCES = getopt.c getopt1.c vfprintf.c number.c
+
+DEFS = @DEFS@ $(DEFSADD)
+
+AM_CFLAGS = @CFLAGS@
+
+MAINTAINERCLEANFILES = Makefile.in number.c
+CLEANFILES = testmul specialnumber muldigits.h
+
+newnumber.o: number.c muldigits.h
+       $(CC) $(CFLAGS) $(INCLUDES) -c -DMULDIGITS -o newnumber.o $(srcdir)/number.c
+
+muldigits.h: testmul
+       @echo "The following may take up to 10 minutes."
+       ./testmul > muldigits.h
+
+testmul: testmul.o number.o
+       $(CC) $(CFLAGS) -o testmul testmul.o number.o
+
+specialnumber: newnumber.o
+       cp newnumber.o number.o
diff --git a/lib/Makefile.in b/lib/Makefile.in
new file mode 100644 (file)
index 0000000..549e2e1
--- /dev/null
@@ -0,0 +1,399 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+subdir = lib
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libbc_a_AR = $(AR) $(ARFLAGS)
+libbc_a_LIBADD =
+am_libbc_a_OBJECTS = getopt.$(OBJEXT) getopt1.$(OBJEXT) \
+       vfprintf.$(OBJEXT) number.$(OBJEXT)
+libbc_a_OBJECTS = $(am_libbc_a_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libbc_a_SOURCES)
+DIST_SOURCES = $(libbc_a_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BC_VERSION = @BC_VERSION@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DC_VERSION = @DC_VERSION@
+DEFS = @DEFS@ $(DEFSADD)
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+READLINELIB = @READLINELIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+noinst_LIBRARIES = libbc.a
+INCLUDES = -I. -I.. -I$(srcdir)/../h
+libbc_a_SOURCES = getopt.c getopt1.c vfprintf.c number.c
+AM_CFLAGS = @CFLAGS@
+MAINTAINERCLEANFILES = Makefile.in number.c
+CLEANFILES = testmul specialnumber muldigits.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  lib/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  lib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libbc.a: $(libbc_a_OBJECTS) $(libbc_a_DEPENDENCIES) 
+       -rm -f libbc.a
+       $(libbc_a_AR) libbc.a $(libbc_a_OBJECTS) $(libbc_a_LIBADD)
+       $(RANLIB) libbc.a
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/number.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vfprintf.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+         test -n "$$unique" || unique=$$empty_fix; \
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+           $$tags $$unique; \
+       fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-noinstLIBRARIES ctags distclean distclean-compile \
+       distclean-generic distclean-tags distdir dvi dvi-am html \
+       html-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-info \
+       install-info-am install-man install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+       uninstall-am uninstall-info-am
+
+
+newnumber.o: number.c muldigits.h
+       $(CC) $(CFLAGS) $(INCLUDES) -c -DMULDIGITS -o newnumber.o $(srcdir)/number.c
+
+muldigits.h: testmul
+       @echo "The following may take up to 10 minutes."
+       ./testmul > muldigits.h
+
+testmul: testmul.o number.o
+       $(CC) $(CFLAGS) -o testmul testmul.o number.o
+
+specialnumber: newnumber.o
+       cp newnumber.o number.o
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/getopt.c b/lib/getopt.c
new file mode 100644 (file)
index 0000000..b270074
--- /dev/null
@@ -0,0 +1,1213 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to drepper@gnu.org
+   before changing it!
+
+   Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
+   Inc.
+
+   This file is part of the GNU C Library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.  */
+\f
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+   Ditto for AIX 3.2 and <stdlib.h>.  */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#  define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library.  */
+
+#include <string.h>
+
+#ifdef VMS
+# include <unixlib.h>
+#endif
+
+#ifdef USEGETTEXT
+#ifdef _LIBC
+# include <libintl.h>
+#else
+/* This is for other GNU distributions with internationalized messages.  */
+# include "gettext.h"
+#endif
+#define _(msgid) gettext (msgid)
+#else
+#define _(msgid) (msgid)
+#endif
+
+#if defined _LIBC && defined USE_IN_LIBIO
+# include <wchar.h>
+#endif
+
+#ifndef attribute_hidden
+# define attribute_hidden
+#endif
+
+/* 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 POSIXLY_CORRECT 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.  */
+
+#include "getopt.h"
+
+/* 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 -1, 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.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+int __getopt_initialized attribute_hidden;
+
+/* 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;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT 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.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-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 1.
+   Using `-' as the first character of the list of option characters
+   selects 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 -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+\f
+#ifndef        __GNU_LIBRARY__
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+#endif /* not __GNU_LIBRARY__ */
+\f
+/* 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;
+
+#ifdef _LIBC
+/* Stored original parameters.
+   XXX This is no good solution.  We should rather copy the args so
+   that we can compare them later.  But we must not use malloc(3).  */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c  */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+#  define SWAP_FLAGS(ch1, ch2) \
+  if (nonoption_flags_len > 0)                                               \
+    {                                                                        \
+      char __tmp = __getopt_nonoption_flags[ch1];                            \
+      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];         \
+      __getopt_nonoption_flags[ch2] = __tmp;                                 \
+    }
+# else
+#  define SWAP_FLAGS(ch1, ch2)
+# endif
+#else  /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+static void
+exchange (char **argv)
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  /* First make sure the handling of the `__getopt_nonoption_flags'
+     string can work normally.  Our top argument must be in the range
+     of the string.  */
+  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+    {
+      /* We must extend the array.  The user plays games with us and
+        presents new arguments.  */
+      char *new_str = malloc (top + 1);
+      if (new_str == NULL)
+       nonoption_flags_len = nonoption_flags_max_len = 0;
+      else
+       {
+         memset (__mempcpy (new_str, __getopt_nonoption_flags,
+                            nonoption_flags_max_len),
+                 '\0', top + 1 - nonoption_flags_max_len);
+         nonoption_flags_max_len = top + 1;
+         __getopt_nonoption_flags = new_str;
+       }
+    }
+#endif
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+       {
+         /* Bottom segment is the short one.  */
+         int len = middle - bottom;
+         register int i;
+
+         /* Swap it with the top part of the top segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[top - (middle - bottom) + i];
+             argv[top - (middle - bottom) + i] = tem;
+             SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+           }
+         /* Exclude the moved bottom segment from further swapping.  */
+         top -= len;
+       }
+      else
+       {
+         /* Top segment is the short one.  */
+         int len = top - middle;
+         register int i;
+
+         /* Swap it with the bottom part of the bottom segment.  */
+         for (i = 0; i < len; i++)
+           {
+             tem = argv[bottom + i];
+             argv[bottom + i] = argv[middle + i];
+             argv[middle + i] = tem;
+             SWAP_FLAGS (bottom + i, middle + i);
+           }
+         /* Exclude the moved top segment from further swapping.  */
+         bottom += len;
+       }
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+static const char *
+_getopt_initialize (int argc, char *const *argv, const char *optstring)
+{
+  /* 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;
+
+  nextchar = NULL;
+
+  posixly_correct = getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    {
+      ordering = RETURN_IN_ORDER;
+      ++optstring;
+    }
+  else if (optstring[0] == '+')
+    {
+      ordering = REQUIRE_ORDER;
+      ++optstring;
+    }
+  else if (posixly_correct != NULL)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+  if (posixly_correct == NULL
+      && argc == __libc_argc && argv == __libc_argv)
+    {
+      if (nonoption_flags_max_len == 0)
+       {
+         if (__getopt_nonoption_flags == NULL
+             || __getopt_nonoption_flags[0] == '\0')
+           nonoption_flags_max_len = -1;
+         else
+           {
+             const char *orig_str = __getopt_nonoption_flags;
+             int len = nonoption_flags_max_len = strlen (orig_str);
+             if (nonoption_flags_max_len < argc)
+               nonoption_flags_max_len = argc;
+             __getopt_nonoption_flags =
+               (char *) malloc (nonoption_flags_max_len);
+             if (__getopt_nonoption_flags == NULL)
+               nonoption_flags_max_len = -1;
+             else
+               memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+                       '\0', nonoption_flags_max_len - len);
+           }
+       }
+      nonoption_flags_len = nonoption_flags_max_len;
+    }
+  else
+    nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+\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 the option 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 -1.
+   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.
+   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', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (int argc, char *const *argv,
+                 const char *optstring, const struct option *longopts,
+                 int *longind, int long_only)
+{
+  int print_errors = opterr;
+  if (optstring[0] == ':')
+    print_errors = 0;
+
+  if (argc < 1)
+    return -1;
+
+  optarg = NULL;
+
+  if (optind == 0 || !__getopt_initialized)
+    {
+      if (optind == 0)
+       optind = 1;     /* Don't scan ARGV[0], the program name.  */
+      optstring = _getopt_initialize (argc, argv, optstring);
+      __getopt_initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'              \
+                     || (optind < nonoption_flags_len                        \
+                         && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+        moved back by the user (who may also have changed the arguments).  */
+      if (last_nonopt > optind)
+       last_nonopt = optind;
+      if (first_nonopt > optind)
+       first_nonopt = optind;
+
+      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 ((char **) argv);
+         else if (last_nonopt != optind)
+           first_nonopt = optind;
+
+         /* Skip any additional non-options
+            and extend the range of non-options previously skipped.  */
+
+         while (optind < argc && NONOPTION_P)
+           optind++;
+         last_nonopt = optind;
+       }
+
+      /* The 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 != argc && !strcmp (argv[optind], "--"))
+       {
+         optind++;
+
+         if (first_nonopt != last_nonopt && last_nonopt != optind)
+           exchange ((char **) argv);
+         else if (first_nonopt == last_nonopt)
+           first_nonopt = optind;
+         last_nonopt = argc;
+
+         optind = argc;
+       }
+
+      /* If we have done all the ARGV-elements, stop the scan
+        and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+       {
+         /* 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 -1;
+       }
+
+      /* 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 (NONOPTION_P)
+       {
+         if (ordering == REQUIRE_ORDER)
+           return -1;
+         optarg = argv[optind++];
+         return 1;
+       }
+
+      /* We have found another option-ARGV-element.
+        Skip the initial punctuation.  */
+
+      nextchar = (argv[optind] + 1
+                 + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[optind][1] == '-'
+         || (long_only
+             && (argv[optind][2] || !strchr (optstring, argv[optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+       /* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+        or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+       if (!strncmp (p->name, nextchar, nameend - nextchar))
+         {
+           if ((unsigned int) (nameend - nextchar)
+               == (unsigned int) strlen (p->name))
+             {
+               /* Exact match found.  */
+               pfound = p;
+               indfound = option_index;
+               exact = 1;
+               break;
+             }
+           else if (pfound == NULL)
+             {
+               /* First nonexact match found.  */
+               pfound = p;
+               indfound = option_index;
+             }
+           else if (long_only
+                    || pfound->has_arg != p->has_arg
+                    || pfound->flag != p->flag
+                    || pfound->val != p->val)
+             /* Second or later nonexact match found.  */
+             ambig = 1;
+         }
+
+      if (ambig && !exact)
+       {
+         if (print_errors)
+           {
+#if defined _LIBC && defined USE_IN_LIBIO
+             char *buf;
+
+             if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
+                             argv[0], argv[optind]) >= 0)
+               {
+
+                 if (_IO_fwide (stderr, 0) > 0)
+                   __fwprintf (stderr, L"%s", buf);
+                 else
+                   fputs (buf, stderr);
+
+                 free (buf);
+               }
+#else
+             fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+                      argv[0], argv[optind]);
+#endif
+           }
+         nextchar += strlen (nextchar);
+         optind++;
+         optopt = 0;
+         return '?';
+       }
+
+      if (pfound != NULL)
+       {
+         option_index = indfound;
+         optind++;
+         if (*nameend)
+           {
+             /* Don't test has_arg with >, because some C compilers don't
+                allow it to be used on enums.  */
+             if (pfound->has_arg)
+               optarg = nameend + 1;
+             else
+               {
+                 if (print_errors)
+                   {
+#if defined _LIBC && defined USE_IN_LIBIO
+                     char *buf;
+                     int n;
+#endif
+
+                     if (argv[optind - 1][1] == '-')
+                       {
+                         /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+                         n = __asprintf (&buf, _("\
+%s: option `--%s' doesn't allow an argument\n"),
+                                         argv[0], pfound->name);
+#else
+                         fprintf (stderr, _("\
+%s: option `--%s' doesn't allow an argument\n"),
+                                  argv[0], pfound->name);
+#endif
+                       }
+                     else
+                       {
+                         /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+                         n = __asprintf (&buf, _("\
+%s: option `%c%s' doesn't allow an argument\n"),
+                                         argv[0], argv[optind - 1][0],
+                                         pfound->name);
+#else
+                         fprintf (stderr, _("\
+%s: option `%c%s' doesn't allow an argument\n"),
+                                  argv[0], argv[optind - 1][0], pfound->name);
+#endif
+                       }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+                     if (n >= 0)
+                       {
+                         if (_IO_fwide (stderr, 0) > 0)
+                           __fwprintf (stderr, L"%s", buf);
+                         else
+                           fputs (buf, stderr);
+
+                         free (buf);
+                       }
+#endif
+                   }
+
+                 nextchar += strlen (nextchar);
+
+                 optopt = pfound->val;
+                 return '?';
+               }
+           }
+         else if (pfound->has_arg == 1)
+           {
+             if (optind < argc)
+               optarg = argv[optind++];
+             else
+               {
+                 if (print_errors)
+                   {
+#if defined _LIBC && defined USE_IN_LIBIO
+                     char *buf;
+
+                     if (__asprintf (&buf, _("\
+%s: option `%s' requires an argument\n"),
+                                     argv[0], argv[optind - 1]) >= 0)
+                       {
+                         if (_IO_fwide (stderr, 0) > 0)
+                           __fwprintf (stderr, L"%s", buf);
+                         else
+                           fputs (buf, stderr);
+
+                         free (buf);
+                       }
+#else
+                     fprintf (stderr,
+                              _("%s: option `%s' requires an argument\n"),
+                              argv[0], argv[optind - 1]);
+#endif
+                   }
+                 nextchar += strlen (nextchar);
+                 optopt = pfound->val;
+                 return optstring[0] == ':' ? ':' : '?';
+               }
+           }
+         nextchar += strlen (nextchar);
+         if (longind != NULL)
+           *longind = option_index;
+         if (pfound->flag)
+           {
+             *(pfound->flag) = pfound->val;
+             return 0;
+           }
+         return pfound->val;
+       }
+
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+        or the option starts with '--' or is not a valid short
+        option, then it's an error.
+        Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+         || strchr (optstring, *nextchar) == NULL)
+       {
+         if (print_errors)
+           {
+#if defined _LIBC && defined USE_IN_LIBIO
+             char *buf;
+             int n;
+#endif
+
+             if (argv[optind][1] == '-')
+               {
+                 /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+                 n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
+                                 argv[0], nextchar);
+#else
+                 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+                          argv[0], nextchar);
+#endif
+               }
+             else
+               {
+                 /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+                 n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
+                                 argv[0], argv[optind][0], nextchar);
+#else
+                 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+                          argv[0], argv[optind][0], nextchar);
+#endif
+               }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+             if (n >= 0)
+               {
+                 if (_IO_fwide (stderr, 0) > 0)
+                   __fwprintf (stderr, L"%s", buf);
+                 else
+                   fputs (buf, stderr);
+
+                 free (buf);
+               }
+#endif
+           }
+         nextchar = (char *) "";
+         optind++;
+         optopt = 0;
+         return '?';
+       }
+    }
+
+  /* Look at and handle the next short option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = strchr (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+       if (print_errors)
+         {
+#if defined _LIBC && defined USE_IN_LIBIO
+             char *buf;
+             int n;
+#endif
+
+           if (posixly_correct)
+             {
+               /* 1003.2 specifies the format of this message.  */
+#if defined _LIBC && defined USE_IN_LIBIO
+               n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
+                               argv[0], c);
+#else
+               fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
+#endif
+             }
+           else
+             {
+#if defined _LIBC && defined USE_IN_LIBIO
+               n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
+                               argv[0], c);
+#else
+               fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
+#endif
+             }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+           if (n >= 0)
+             {
+               if (_IO_fwide (stderr, 0) > 0)
+                 __fwprintf (stderr, L"%s", buf);
+               else
+                 fputs (buf, stderr);
+
+               free (buf);
+             }
+#endif
+         }
+       optopt = c;
+       return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+       char *nameend;
+       const struct option *p;
+       const struct option *pfound = NULL;
+       int exact = 0;
+       int ambig = 0;
+       int indfound = 0;
+       int option_index;
+
+       /* 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 == argc)
+         {
+           if (print_errors)
+             {
+               /* 1003.2 specifies the format of this message.  */
+#if defined _LIBC && defined USE_IN_LIBIO
+               char *buf;
+
+               if (__asprintf (&buf,
+                               _("%s: option requires an argument -- %c\n"),
+                               argv[0], c) >= 0)
+                 {
+                   if (_IO_fwide (stderr, 0) > 0)
+                     __fwprintf (stderr, L"%s", buf);
+                   else
+                     fputs (buf, stderr);
+
+                   free (buf);
+                 }
+#else
+               fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+                        argv[0], c);
+#endif
+             }
+           optopt = c;
+           if (optstring[0] == ':')
+             c = ':';
+           else
+             c = '?';
+           return c;
+         }
+       else
+         /* We already incremented `optind' once;
+            increment it again when taking next ARGV-elt as argument.  */
+         optarg = argv[optind++];
+
+       /* optarg is now the argument, see if it's in the
+          table of longopts.  */
+
+       for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+         /* Do nothing.  */ ;
+
+       /* Test all long options for either exact match
+          or abbreviated matches.  */
+       for (p = longopts, option_index = 0; p->name; p++, option_index++)
+         if (!strncmp (p->name, nextchar, nameend - nextchar))
+           {
+             if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+               {
+                 /* Exact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+                 exact = 1;
+                 break;
+               }
+             else if (pfound == NULL)
+               {
+                 /* First nonexact match found.  */
+                 pfound = p;
+                 indfound = option_index;
+               }
+             else
+               /* Second or later nonexact match found.  */
+               ambig = 1;
+           }
+       if (ambig && !exact)
+         {
+           if (print_errors)
+             {
+#if defined _LIBC && defined USE_IN_LIBIO
+               char *buf;
+
+               if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
+                               argv[0], argv[optind]) >= 0)
+                 {
+                   if (_IO_fwide (stderr, 0) > 0)
+                     __fwprintf (stderr, L"%s", buf);
+                   else
+                     fputs (buf, stderr);
+
+                   free (buf);
+                 }
+#else
+               fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+                        argv[0], argv[optind]);
+#endif
+             }
+           nextchar += strlen (nextchar);
+           optind++;
+           return '?';
+         }
+       if (pfound != NULL)
+         {
+           option_index = indfound;
+           if (*nameend)
+             {
+               /* Don't test has_arg with >, because some C compilers don't
+                  allow it to be used on enums.  */
+               if (pfound->has_arg)
+                 optarg = nameend + 1;
+               else
+                 {
+                   if (print_errors)
+                     {
+#if defined _LIBC && defined USE_IN_LIBIO
+                       char *buf;
+
+                       if (__asprintf (&buf, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+                                       argv[0], pfound->name) >= 0)
+                         {
+                           if (_IO_fwide (stderr, 0) > 0)
+                             __fwprintf (stderr, L"%s", buf);
+                           else
+                             fputs (buf, stderr);
+
+                           free (buf);
+                         }
+#else
+                       fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+                                argv[0], pfound->name);
+#endif
+                     }
+
+                   nextchar += strlen (nextchar);
+                   return '?';
+                 }
+             }
+           else if (pfound->has_arg == 1)
+             {
+               if (optind < argc)
+                 optarg = argv[optind++];
+               else
+                 {
+                   if (print_errors)
+                     {
+#if defined _LIBC && defined USE_IN_LIBIO
+                       char *buf;
+
+                       if (__asprintf (&buf, _("\
+%s: option `%s' requires an argument\n"),
+                                       argv[0], argv[optind - 1]) >= 0)
+                         {
+                           if (_IO_fwide (stderr, 0) > 0)
+                             __fwprintf (stderr, L"%s", buf);
+                           else
+                             fputs (buf, stderr);
+
+                           free (buf);
+                         }
+#else
+                       fprintf (stderr,
+                                _("%s: option `%s' requires an argument\n"),
+                                argv[0], argv[optind - 1]);
+#endif
+                     }
+                   nextchar += strlen (nextchar);
+                   return optstring[0] == ':' ? ':' : '?';
+                 }
+             }
+           nextchar += strlen (nextchar);
+           if (longind != NULL)
+             *longind = option_index;
+           if (pfound->flag)
+             {
+               *(pfound->flag) = pfound->val;
+               return 0;
+             }
+           return pfound->val;
+         }
+         nextchar = NULL;
+         return 'W';   /* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+       if (temp[2] == ':')
+         {
+           /* This is an option that accepts an argument optionally.  */
+           if (*nextchar != '\0')
+             {
+               optarg = nextchar;
+               optind++;
+             }
+           else
+             optarg = NULL;
+           nextchar = NULL;
+         }
+       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 == argc)
+             {
+               if (print_errors)
+                 {
+                   /* 1003.2 specifies the format of this message.  */
+#if defined _LIBC && defined USE_IN_LIBIO
+                   char *buf;
+
+                   if (__asprintf (&buf, _("\
+%s: option requires an argument -- %c\n"),
+                                   argv[0], c) >= 0)
+                     {
+                       if (_IO_fwide (stderr, 0) > 0)
+                         __fwprintf (stderr, L"%s", buf);
+                       else
+                         fputs (buf, stderr);
+
+                       free (buf);
+                     }
+#else
+                   fprintf (stderr,
+                            _("%s: option requires an argument -- %c\n"),
+                            argv[0], c);
+#endif
+                 }
+               optopt = c;
+               if (optstring[0] == ':')
+                 c = ':';
+               else
+                 c = '?';
+             }
+           else
+             /* We already incremented `optind' once;
+                increment it again when taking next ARGV-elt as argument.  */
+             optarg = argv[optind++];
+           nextchar = NULL;
+         }
+      }
+    return c;
+  }
+}
+
+int
+getopt (int argc, char *const *argv, const char *optstring)
+{
+  return _getopt_internal (argc, argv, optstring,
+                          (const struct option *) 0,
+                          (int *) 0,
+                          0);
+}
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (int argc, char **argv)
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/lib/getopt1.c b/lib/getopt1.c
new file mode 100644 (file)
index 0000000..e362462
--- /dev/null
@@ -0,0 +1,185 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+
+   Copyright (C) 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996,
+   1997, 1998, 2003 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.  */
+\f
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef _LIBC
+# include <getopt.h>
+#else
+# include "getopt.h"
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef        NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (int argc,
+            char *const *argv,
+            const char *options,
+            const struct option *long_options,
+            int *opt_index)
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (int argc,
+                 char *const *argv,
+                 const char *options,
+                 const struct option *long_options,
+                 int *opt_index)
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+# ifdef _LIBC
+libc_hidden_def (getopt_long)
+libc_hidden_def (getopt_long_only)
+# endif
+
+#endif /* Not ELIDE_CODE.  */
+\f
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+       {"add", 1, 0, 0},
+       {"append", 0, 0, 0},
+       {"delete", 1, 0, 0},
+       {"verbose", 0, 0, 0},
+       {"create", 0, 0, 0},
+       {"file", 1, 0, 0},
+       {0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+                      long_options, &option_index);
+      if (c == -1)
+       break;
+
+      switch (c)
+       {
+       case 0:
+         printf ("option %s", long_options[option_index].name);
+         if (optarg)
+           printf (" with arg %s", optarg);
+         printf ("\n");
+         break;
+
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (digit_optind != 0 && digit_optind != this_option_optind)
+           printf ("digits occur in two different argv-elements.\n");
+         digit_optind = this_option_optind;
+         printf ("option %c\n", c);
+         break;
+
+       case 'a':
+         printf ("option a\n");
+         break;
+
+       case 'b':
+         printf ("option b\n");
+         break;
+
+       case 'c':
+         printf ("option c with value `%s'\n", optarg);
+         break;
+
+       case 'd':
+         printf ("option d with value `%s'\n", optarg);
+         break;
+
+       case '?':
+         break;
+
+       default:
+         printf ("?? getopt returned character code 0%o ??\n", c);
+       }
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+       printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/lib/number.c b/lib/number.c
new file mode 100644 (file)
index 0000000..e211840
--- /dev/null
@@ -0,0 +1,1804 @@
+/* number.c: Implements arbitrary precision numbers. */
+/*
+    Copyright (C) 1991, 1992, 1993, 1994, 1997, 2000 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 of the License , or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; see the file COPYING.  If not, write to:
+
+      The Free Software Foundation, Inc.
+      51 Franklin Street, Fifth Floor
+      Boston, MA 02110-1301  USA
+
+
+    You may contact the author by:
+       e-mail:  philnelson@acm.org
+      us-mail:  Philip A. Nelson
+                Computer Science Department, 9062
+                Western Washington University
+                Bellingham, WA 98226-9062
+       
+*************************************************************************/
+
+#include <stdio.h>
+#include <config.h>
+#include <number.h>
+#include <assert.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <ctype.h>
+
+/* Prototypes needed for external utility routines. */
+
+#define bc_rt_warn rt_warn
+#define bc_rt_error rt_error
+#define bc_out_of_memory out_of_memory
+
+_PROTOTYPE(void rt_warn, (const char *mesg ,...));
+_PROTOTYPE(void rt_error, (const char *mesg ,...));
+_PROTOTYPE(void out_of_memory, (void));
+
+/* Storage used for special numbers. */
+bc_num _zero_;
+bc_num _one_;
+bc_num _two_;
+
+static bc_num _bc_Free_list = NULL;
+
+/* new_num allocates a number and sets fields to known values. */
+
+bc_num
+bc_new_num (length, scale)
+     int length, scale;
+{
+  bc_num temp;
+
+  if (_bc_Free_list != NULL) {
+    temp = _bc_Free_list;
+    _bc_Free_list = temp->n_next;
+  } else {
+    temp = (bc_num) malloc (sizeof(bc_struct));
+    if (temp == NULL) bc_out_of_memory ();
+  }
+  temp->n_sign = PLUS;
+  temp->n_len = length;
+  temp->n_scale = scale;
+  temp->n_refs = 1;
+  temp->n_ptr = (char *) malloc (length+scale);
+  if (temp->n_ptr == NULL) bc_out_of_memory();
+  temp->n_value = temp->n_ptr;
+  memset (temp->n_ptr, 0, length+scale);
+  return temp;
+}
+
+/* "Frees" a bc_num NUM.  Actually decreases reference count and only
+   frees the storage if reference count is zero. */
+
+void
+bc_free_num (num)
+    bc_num *num;
+{
+  if (*num == NULL) return;
+  (*num)->n_refs--;
+  if ((*num)->n_refs == 0) {
+    if ((*num)->n_ptr)
+      free ((*num)->n_ptr);
+    (*num)->n_next = _bc_Free_list;
+    _bc_Free_list = *num;
+  }
+  *num = NULL;
+}
+
+
+/* Intitialize the number package! */
+
+void
+bc_init_numbers ()
+{
+  _zero_ = bc_new_num (1,0);
+  _one_  = bc_new_num (1,0);
+  _one_->n_value[0] = 1;
+  _two_  = bc_new_num (1,0);
+  _two_->n_value[0] = 2;
+}
+
+
+/* Make a copy of a number!  Just increments the reference count! */
+
+bc_num
+bc_copy_num (num)
+     bc_num num;
+{
+  num->n_refs++;
+  return num;
+}
+
+
+/* Initialize a number NUM by making it a copy of zero. */
+
+void
+bc_init_num (num)
+     bc_num *num;
+{
+  *num = bc_copy_num (_zero_);
+}
+
+/* For many things, we may have leading zeros in a number NUM.
+   _bc_rm_leading_zeros just moves the data "value" pointer to the
+   correct place and adjusts the length. */
+
+static void
+_bc_rm_leading_zeros (num)
+     bc_num num;
+{
+  /* We can move n_value to point to the first non zero digit! */
+  while (*num->n_value == 0 && num->n_len > 1) {
+    num->n_value++;
+    num->n_len--;
+  }
+}
+
+
+/* Compare two bc numbers.  Return value is 0 if equal, -1 if N1 is less
+   than N2 and +1 if N1 is greater than N2.  If USE_SIGN is false, just
+   compare the magnitudes. */
+
+static int
+_bc_do_compare (n1, n2, use_sign, ignore_last)
+     bc_num n1, n2;
+     int use_sign;
+     int ignore_last;
+{
+  char *n1ptr, *n2ptr;
+  int  count;
+
+  /* First, compare signs. */
+  if (use_sign && n1->n_sign != n2->n_sign)
+    {
+      if (n1->n_sign == PLUS)
+       return (1);     /* Positive N1 > Negative N2 */
+      else
+       return (-1);    /* Negative N1 < Positive N1 */
+    }
+
+  /* Now compare the magnitude. */
+  if (n1->n_len != n2->n_len)
+    {
+      if (n1->n_len > n2->n_len)
+       {
+         /* Magnitude of n1 > n2. */
+         if (!use_sign || n1->n_sign == PLUS)
+           return (1);
+         else
+           return (-1);
+       }
+      else
+       {
+         /* Magnitude of n1 < n2. */
+         if (!use_sign || n1->n_sign == PLUS)
+           return (-1);
+         else
+           return (1);
+       }
+    }
+
+  /* If we get here, they have the same number of integer digits.
+     check the integer part and the equal length part of the fraction. */
+  count = n1->n_len + MIN (n1->n_scale, n2->n_scale);
+  n1ptr = n1->n_value;
+  n2ptr = n2->n_value;
+
+  while ((count > 0) && (*n1ptr == *n2ptr))
+    {
+      n1ptr++;
+      n2ptr++;
+      count--;
+    }
+  if (ignore_last && count == 1 && n1->n_scale == n2->n_scale)
+    return (0);
+  if (count != 0)
+    {
+      if (*n1ptr > *n2ptr)
+       {
+         /* Magnitude of n1 > n2. */
+         if (!use_sign || n1->n_sign == PLUS)
+           return (1);
+         else
+           return (-1);
+       }
+      else
+       {
+         /* Magnitude of n1 < n2. */
+         if (!use_sign || n1->n_sign == PLUS)
+           return (-1);
+         else
+           return (1);
+       }
+    }
+
+  /* They are equal up to the last part of the equal part of the fraction. */
+  if (n1->n_scale != n2->n_scale)
+    {
+      if (n1->n_scale > n2->n_scale)
+       {
+         for (count = n1->n_scale-n2->n_scale; count>0; count--)
+           if (*n1ptr++ != 0)
+             {
+               /* Magnitude of n1 > n2. */
+               if (!use_sign || n1->n_sign == PLUS)
+                 return (1);
+               else
+                 return (-1);
+             }
+       }
+      else
+       {
+         for (count = n2->n_scale-n1->n_scale; count>0; count--)
+           if (*n2ptr++ != 0)
+             {
+               /* Magnitude of n1 < n2. */
+               if (!use_sign || n1->n_sign == PLUS)
+                 return (-1);
+               else
+                 return (1);
+             }
+       }
+    }
+
+  /* They must be equal! */
+  return (0);
+}
+
+
+/* This is the "user callable" routine to compare numbers N1 and N2. */
+
+int
+bc_compare (n1, n2)
+     bc_num n1, n2;
+{
+  return _bc_do_compare (n1, n2, TRUE, FALSE);
+}
+
+/* In some places we need to check if the number is negative. */
+
+char
+bc_is_neg (num)
+     bc_num num;
+{
+  return num->n_sign == MINUS;
+}
+
+/* In some places we need to check if the number NUM is zero. */
+
+char
+bc_is_zero (num)
+     bc_num num;
+{
+  int  count;
+  char *nptr;
+
+  /* Quick check. */
+  if (num == _zero_) return TRUE;
+
+  /* Initialize */
+  count = num->n_len + num->n_scale;
+  nptr = num->n_value;
+
+  /* The check */
+  while ((count > 0) && (*nptr++ == 0)) count--;
+
+  if (count != 0)
+    return FALSE;
+  else
+    return TRUE;
+}
+
+/* In some places we need to check if the number NUM is almost zero.
+   Specifically, all but the last digit is 0 and the last digit is 1.
+   Last digit is defined by scale. */
+
+char
+bc_is_near_zero (num, scale)
+     bc_num num;
+     int scale;
+{
+  int  count;
+  char *nptr;
+
+  /* Error checking */
+  if (scale > num->n_scale)
+    scale = num->n_scale;
+
+  /* Initialize */
+  count = num->n_len + scale;
+  nptr = num->n_value;
+
+  /* The check */
+  while ((count > 0) && (*nptr++ == 0)) count--;
+
+  if (count != 0 && (count != 1 || *--nptr != 1))
+    return FALSE;
+  else
+    return TRUE;
+}
+
+
+/* Perform addition: N1 is added to N2 and the value is
+   returned.  The signs of N1 and N2 are ignored.
+   SCALE_MIN is to set the minimum scale of the result. */
+
+static bc_num
+_bc_do_add (n1, n2, scale_min)
+     bc_num n1, n2;
+     int scale_min;
+{
+  bc_num sum;
+  int sum_scale, sum_digits;
+  char *n1ptr, *n2ptr, *sumptr;
+  int carry, n1bytes, n2bytes;
+  int count;
+
+  /* Prepare sum. */
+  sum_scale = MAX (n1->n_scale, n2->n_scale);
+  sum_digits = MAX (n1->n_len, n2->n_len) + 1;
+  sum = bc_new_num (sum_digits, MAX(sum_scale, scale_min));
+
+  /* Zero extra digits made by scale_min. */
+  if (scale_min > sum_scale)
+    {
+      sumptr = (char *) (sum->n_value + sum_scale + sum_digits);
+      for (count = scale_min - sum_scale; count > 0; count--)
+       *sumptr++ = 0;
+    }
+
+  /* Start with the fraction part.  Initialize the pointers. */
+  n1bytes = n1->n_scale;
+  n2bytes = n2->n_scale;
+  n1ptr = (char *) (n1->n_value + n1->n_len + n1bytes - 1);
+  n2ptr = (char *) (n2->n_value + n2->n_len + n2bytes - 1);
+  sumptr = (char *) (sum->n_value + sum_scale + sum_digits - 1);
+
+  /* Add the fraction part.  First copy the longer fraction.*/
+  if (n1bytes != n2bytes)
+    {
+      if (n1bytes > n2bytes)
+       while (n1bytes>n2bytes)
+         { *sumptr-- = *n1ptr--; n1bytes--;}
+      else
+       while (n2bytes>n1bytes)
+         { *sumptr-- = *n2ptr--; n2bytes--;}
+    }
+
+  /* Now add the remaining fraction part and equal size integer parts. */
+  n1bytes += n1->n_len;
+  n2bytes += n2->n_len;
+  carry = 0;
+  while ((n1bytes > 0) && (n2bytes > 0))
+    {
+      *sumptr = *n1ptr-- + *n2ptr-- + carry;
+      if (*sumptr > (BASE-1))
+       {
+          carry = 1;
+          *sumptr -= BASE;
+       }
+      else
+       carry = 0;
+      sumptr--;
+      n1bytes--;
+      n2bytes--;
+    }
+
+  /* Now add carry the longer integer part. */
+  if (n1bytes == 0)
+    { n1bytes = n2bytes; n1ptr = n2ptr; }
+  while (n1bytes-- > 0)
+    {
+      *sumptr = *n1ptr-- + carry;
+      if (*sumptr > (BASE-1))
+       {
+          carry = 1;
+          *sumptr -= BASE;
+        }
+      else
+       carry = 0;
+      sumptr--;
+    }
+
+  /* Set final carry. */
+  if (carry == 1)
+    *sumptr += 1;
+
+  /* Adjust sum and return. */
+  _bc_rm_leading_zeros (sum);
+  return sum;
+}
+
+
+/* Perform subtraction: N2 is subtracted from N1 and the value is
+   returned.  The signs of N1 and N2 are ignored.  Also, N1 is
+   assumed to be larger than N2.  SCALE_MIN is the minimum scale
+   of the result. */
+
+static bc_num
+_bc_do_sub (n1, n2, scale_min)
+     bc_num n1, n2;
+     int scale_min;
+{
+  bc_num diff;
+  int diff_scale, diff_len;
+  int min_scale, min_len;
+  char *n1ptr, *n2ptr, *diffptr;
+  int borrow, count, val;
+
+  /* Allocate temporary storage. */
+  diff_len = MAX (n1->n_len, n2->n_len);
+  diff_scale = MAX (n1->n_scale, n2->n_scale);
+  min_len = MIN  (n1->n_len, n2->n_len);
+  min_scale = MIN (n1->n_scale, n2->n_scale);
+  diff = bc_new_num (diff_len, MAX(diff_scale, scale_min));
+
+  /* Zero extra digits made by scale_min. */
+  if (scale_min > diff_scale)
+    {
+      diffptr = (char *) (diff->n_value + diff_len + diff_scale);
+      for (count = scale_min - diff_scale; count > 0; count--)
+       *diffptr++ = 0;
+    }
+
+  /* Initialize the subtract. */
+  n1ptr = (char *) (n1->n_value + n1->n_len + n1->n_scale -1);
+  n2ptr = (char *) (n2->n_value + n2->n_len + n2->n_scale -1);
+  diffptr = (char *) (diff->n_value + diff_len + diff_scale -1);
+
+  /* Subtract the numbers. */
+  borrow = 0;
+
+  /* Take care of the longer scaled number. */
+  if (n1->n_scale != min_scale)
+    {
+      /* n1 has the longer scale */
+      for (count = n1->n_scale - min_scale; count > 0; count--)
+       *diffptr-- = *n1ptr--;
+    }
+  else
+    {
+      /* n2 has the longer scale */
+      for (count = n2->n_scale - min_scale; count > 0; count--)
+       {
+         val = - *n2ptr-- - borrow;
+         if (val < 0)
+           {
+             val += BASE;
+             borrow = 1;
+           }
+         else
+           borrow = 0;
+         *diffptr-- = val;
+       }
+    }
+
+  /* Now do the equal length scale and integer parts. */
+
+  for (count = 0; count < min_len + min_scale; count++)
+    {
+      val = *n1ptr-- - *n2ptr-- - borrow;
+      if (val < 0)
+       {
+         val += BASE;
+         borrow = 1;
+       }
+      else
+       borrow = 0;
+      *diffptr-- = val;
+    }
+
+  /* If n1 has more digits then n2, we now do that subtract. */
+  if (diff_len != min_len)
+    {
+      for (count = diff_len - min_len; count > 0; count--)
+       {
+         val = *n1ptr-- - borrow;
+         if (val < 0)
+           {
+             val += BASE;
+             borrow = 1;
+           }
+         else
+           borrow = 0;
+         *diffptr-- = val;
+       }
+    }
+
+  /* Clean up and return. */
+  _bc_rm_leading_zeros (diff);
+  return diff;
+}
+
+
+/* Here is the full subtract routine that takes care of negative numbers.
+   N2 is subtracted from N1 and the result placed in RESULT.  SCALE_MIN
+   is the minimum scale for the result. */
+
+void
+bc_sub (n1, n2, result, scale_min)
+     bc_num n1, n2, *result;
+     int scale_min;
+{
+  bc_num diff = NULL;
+  int cmp_res;
+  int res_scale;
+
+  if (n1->n_sign != n2->n_sign)
+    {
+      diff = _bc_do_add (n1, n2, scale_min);
+      diff->n_sign = n1->n_sign;
+    }
+  else
+    {
+      /* subtraction must be done. */
+      /* Compare magnitudes. */
+      cmp_res = _bc_do_compare (n1, n2, FALSE, FALSE);
+      switch (cmp_res)
+       {
+       case -1:
+         /* n1 is less than n2, subtract n1 from n2. */
+         diff = _bc_do_sub (n2, n1, scale_min);
+         diff->n_sign = (n2->n_sign == PLUS ? MINUS : PLUS);
+         break;
+       case  0:
+         /* They are equal! return zero! */
+         res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale));
+         diff = bc_new_num (1, res_scale);
+         memset (diff->n_value, 0, res_scale+1);
+         break;
+       case  1:
+         /* n2 is less than n1, subtract n2 from n1. */
+         diff = _bc_do_sub (n1, n2, scale_min);
+         diff->n_sign = n1->n_sign;
+         break;
+       }
+    }
+
+  /* Clean up and return. */
+  bc_free_num (result);
+  *result = diff;
+}
+
+
+/* Here is the full add routine that takes care of negative numbers.
+   N1 is added to N2 and the result placed into RESULT.  SCALE_MIN
+   is the minimum scale for the result. */
+
+void
+bc_add (n1, n2, result, scale_min)
+     bc_num n1, n2, *result;
+     int scale_min;
+{
+  bc_num sum = NULL;
+  int cmp_res;
+  int res_scale;
+
+  if (n1->n_sign == n2->n_sign)
+    {
+      sum = _bc_do_add (n1, n2, scale_min);
+      sum->n_sign = n1->n_sign;
+    }
+  else
+    {
+      /* subtraction must be done. */
+      cmp_res = _bc_do_compare (n1, n2, FALSE, FALSE);  /* Compare magnitudes. */
+      switch (cmp_res)
+       {
+       case -1:
+         /* n1 is less than n2, subtract n1 from n2. */
+         sum = _bc_do_sub (n2, n1, scale_min);
+         sum->n_sign = n2->n_sign;
+         break;
+       case  0:
+         /* They are equal! return zero with the correct scale! */
+         res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale));
+         sum = bc_new_num (1, res_scale);
+         memset (sum->n_value, 0, res_scale+1);
+         break;
+       case  1:
+         /* n2 is less than n1, subtract n2 from n1. */
+         sum = _bc_do_sub (n1, n2, scale_min);
+         sum->n_sign = n1->n_sign;
+       }
+    }
+
+  /* Clean up and return. */
+  bc_free_num (result);
+  *result = sum;
+}
+
+/* Recursive vs non-recursive multiply crossover ranges. */
+#if defined(MULDIGITS)
+#include "muldigits.h"
+#else
+#define MUL_BASE_DIGITS 80
+#endif
+
+int mul_base_digits = MUL_BASE_DIGITS;
+#define MUL_SMALL_DIGITS mul_base_digits/4
+
+/* Multiply utility routines */
+
+static bc_num
+new_sub_num (length, scale, value)
+     int length, scale;
+     char *value;
+{
+  bc_num temp;
+
+  if (_bc_Free_list != NULL) {
+    temp = _bc_Free_list;
+    _bc_Free_list = temp->n_next;
+  } else {
+    temp = (bc_num) malloc (sizeof(bc_struct));
+    if (temp == NULL) bc_out_of_memory ();
+  }
+  temp->n_sign = PLUS;
+  temp->n_len = length;
+  temp->n_scale = scale;
+  temp->n_refs = 1;
+  temp->n_ptr = NULL;
+  temp->n_value = value;
+  return temp;
+}
+
+static void
+_bc_simp_mul (bc_num n1, int n1len, bc_num n2, int n2len, bc_num *prod)
+{
+  char *n1ptr, *n2ptr, *pvptr;
+  char *n1end, *n2end;         /* To the end of n1 and n2. */
+  int indx, sum, prodlen;
+
+  prodlen = n1len+n2len+1;
+
+  *prod = bc_new_num (prodlen, 0);
+
+  n1end = (char *) (n1->n_value + n1len - 1);
+  n2end = (char *) (n2->n_value + n2len - 1);
+  pvptr = (char *) ((*prod)->n_value + prodlen - 1);
+  sum = 0;
+
+  /* Here is the loop... */
+  for (indx = 0; indx < prodlen-1; indx++)
+    {
+      n1ptr = (char *) (n1end - MAX(0, indx-n2len+1));
+      n2ptr = (char *) (n2end - MIN(indx, n2len-1));
+      while ((n1ptr >= n1->n_value) && (n2ptr <= n2end))
+       sum += *n1ptr-- * *n2ptr++;
+      *pvptr-- = sum % BASE;
+      sum = sum / BASE;
+    }
+  *pvptr = sum;
+}
+
+
+/* A special adder/subtractor for the recursive divide and conquer
+   multiply algorithm.  Note: if sub is called, accum must
+   be larger that what is being subtracted.  Also, accum and val
+   must have n_scale = 0.  (e.g. they must look like integers. *) */
+static void
+_bc_shift_addsub (bc_num accum, bc_num val, int shift, int sub)
+{
+  signed char *accp, *valp;
+  int  count, carry;
+
+  count = val->n_len;
+  if (val->n_value[0] == 0)
+    count--;
+  assert (accum->n_len+accum->n_scale >= shift+count);
+  
+  /* Set up pointers and others */
+  accp = (signed char *)(accum->n_value +
+                        accum->n_len + accum->n_scale - shift - 1);
+  valp = (signed char *)(val->n_value + val->n_len - 1);
+  carry = 0;
+
+  if (sub) {
+    /* Subtraction, carry is really borrow. */
+    while (count--) {
+      *accp -= *valp-- + carry;
+      if (*accp < 0) {
+       carry = 1;
+        *accp-- += BASE;
+      } else {
+       carry = 0;
+       accp--;
+      }
+    }
+    while (carry) {
+      *accp -= carry;
+      if (*accp < 0)
+       *accp-- += BASE;
+      else
+       carry = 0;
+    }
+  } else {
+    /* Addition */
+    while (count--) {
+      *accp += *valp-- + carry;
+      if (*accp > (BASE-1)) {
+       carry = 1;
+        *accp-- -= BASE;
+      } else {
+       carry = 0;
+       accp--;
+      }
+    }
+    while (carry) {
+      *accp += carry;
+      if (*accp > (BASE-1))
+       *accp-- -= BASE;
+      else
+       carry = 0;
+    }
+  }
+}
+
+/* Recursive divide and conquer multiply algorithm.  
+   Based on 
+   Let u = u0 + u1*(b^n)
+   Let v = v0 + v1*(b^n)
+   Then uv = (B^2n+B^n)*u1*v1 + B^n*(u1-u0)*(v0-v1) + (B^n+1)*u0*v0
+
+   B is the base of storage, number of digits in u1,u0 close to equal.
+*/
+static void
+_bc_rec_mul (bc_num u, int ulen, bc_num v, int vlen, bc_num *prod)
+{ 
+  bc_num u0, u1, v0, v1;
+  int u0len, v0len;
+  bc_num m1, m2, m3, d1, d2;
+  int n, prodlen, m1zero;
+  int d1len, d2len;
+
+  /* Base case? */
+  if ((ulen+vlen) < mul_base_digits
+      || ulen < MUL_SMALL_DIGITS
+      || vlen < MUL_SMALL_DIGITS ) {
+    _bc_simp_mul (u, ulen, v, vlen, prod);
+    return;
+  }
+
+  /* Calculate n -- the u and v split point in digits. */
+  n = (MAX(ulen, vlen)+1) / 2;
+
+  /* Split u and v. */
+  if (ulen < n) {
+    u1 = bc_copy_num (_zero_);
+    u0 = new_sub_num (ulen,0, u->n_value);
+  } else {
+    u1 = new_sub_num (ulen-n, 0, u->n_value);
+    u0 = new_sub_num (n, 0, u->n_value+ulen-n);
+  }
+  if (vlen < n) {
+    v1 = bc_copy_num (_zero_);
+    v0 = new_sub_num (vlen,0, v->n_value);
+  } else {
+    v1 = new_sub_num (vlen-n, 0, v->n_value);
+    v0 = new_sub_num (n, 0, v->n_value+vlen-n);
+    }
+  _bc_rm_leading_zeros (u1);
+  _bc_rm_leading_zeros (u0);
+  u0len = u0->n_len;
+  _bc_rm_leading_zeros (v1);
+  _bc_rm_leading_zeros (v0);
+  v0len = v0->n_len;
+
+  m1zero = bc_is_zero(u1) || bc_is_zero(v1);
+
+  /* Calculate sub results ... */
+
+  bc_init_num(&d1);
+  bc_init_num(&d2);
+  bc_sub (u1, u0, &d1, 0);
+  d1len = d1->n_len;
+  bc_sub (v0, v1, &d2, 0);
+  d2len = d2->n_len;
+
+
+  /* Do recursive multiplies and shifted adds. */
+  if (m1zero)
+    m1 = bc_copy_num (_zero_);
+  else
+    _bc_rec_mul (u1, u1->n_len, v1, v1->n_len, &m1);
+
+  if (bc_is_zero(d1) || bc_is_zero(d2))
+    m2 = bc_copy_num (_zero_);
+  else
+    _bc_rec_mul (d1, d1len, d2, d2len, &m2);
+
+  if (bc_is_zero(u0) || bc_is_zero(v0))
+    m3 = bc_copy_num (_zero_);
+  else
+    _bc_rec_mul (u0, u0->n_len, v0, v0->n_len, &m3);
+
+  /* Initialize product */
+  prodlen = ulen+vlen+1;
+  *prod = bc_new_num(prodlen, 0);
+
+  if (!m1zero) {
+    _bc_shift_addsub (*prod, m1, 2*n, 0);
+    _bc_shift_addsub (*prod, m1, n, 0);
+  }
+  _bc_shift_addsub (*prod, m3, n, 0);
+  _bc_shift_addsub (*prod, m3, 0, 0);
+  _bc_shift_addsub (*prod, m2, n, d1->n_sign != d2->n_sign);
+
+  /* Now clean up! */
+  bc_free_num (&u1);
+  bc_free_num (&u0);
+  bc_free_num (&v1);
+  bc_free_num (&m1);
+  bc_free_num (&v0);
+  bc_free_num (&m2);
+  bc_free_num (&m3);
+  bc_free_num (&d1);
+  bc_free_num (&d2);
+}
+
+/* The multiply routine.  N2 times N1 is put int PROD with the scale of
+   the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)).
+   */
+
+void
+bc_multiply (n1, n2, prod, scale)
+     bc_num n1, n2, *prod;
+     int scale;
+{
+  bc_num pval; 
+  int len1, len2;
+  int full_scale, prod_scale;
+
+  /* Initialize things. */
+  len1 = n1->n_len + n1->n_scale;
+  len2 = n2->n_len + n2->n_scale;
+  full_scale = n1->n_scale + n2->n_scale;
+  prod_scale = MIN(full_scale,MAX(scale,MAX(n1->n_scale,n2->n_scale)));
+
+  /* Do the multiply */
+  _bc_rec_mul (n1, len1, n2, len2, &pval);
+
+  /* Assign to prod and clean up the number. */
+  pval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );
+  pval->n_value = pval->n_ptr;
+  pval->n_len = len2 + len1 + 1 - full_scale;
+  pval->n_scale = prod_scale;
+  _bc_rm_leading_zeros (pval);
+  if (bc_is_zero (pval))
+    pval->n_sign = PLUS;
+  bc_free_num (prod);
+  *prod = pval;
+}
+
+/* Some utility routines for the divide:  First a one digit multiply.
+   NUM (with SIZE digits) is multiplied by DIGIT and the result is
+   placed into RESULT.  It is written so that NUM and RESULT can be
+   the same pointers.  */
+
+static void
+_one_mult (num, size, digit, result)
+     unsigned char *num;
+     int size, digit;
+     unsigned char *result;
+{
+  int carry, value;
+  unsigned char *nptr, *rptr;
+
+  if (digit == 0)
+    memset (result, 0, size);
+  else
+    {
+      if (digit == 1)
+       memcpy (result, num, size);
+      else
+       {
+         /* Initialize */
+         nptr = (unsigned char *) (num+size-1);
+         rptr = (unsigned char *) (result+size-1);
+         carry = 0;
+
+         while (size-- > 0)
+           {
+             value = *nptr-- * digit + carry;
+             *rptr-- = value % BASE;
+             carry = value / BASE;
+           }
+
+         if (carry != 0) *rptr = carry;
+       }
+    }
+}
+
+
+/* The full division routine. This computes N1 / N2.  It returns
+   0 if the division is ok and the result is in QUOT.  The number of
+   digits after the decimal point is SCALE. It returns -1 if division
+   by zero is tried.  The algorithm is found in Knuth Vol 2. p237. */
+
+int
+bc_divide (n1, n2, quot, scale)
+     bc_num n1, n2, *quot;
+     int scale;
+{
+  bc_num qval;
+  unsigned char *num1, *num2;
+  unsigned char *ptr1, *ptr2, *n2ptr, *qptr;
+  int  scale1, val;
+  unsigned int  len1, len2, scale2, qdigits, extra, count;
+  unsigned int  qdig, qguess, borrow, carry;
+  unsigned char *mval;
+  char zero;
+  unsigned int  norm;
+
+  /* Test for divide by zero. */
+  if (bc_is_zero (n2)) return -1;
+
+  /* Test for divide by 1.  If it is we must truncate. */
+  if (n2->n_scale == 0)
+    {
+      if (n2->n_len == 1 && *n2->n_value == 1)
+       {
+         qval = bc_new_num (n1->n_len, scale);
+         qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS);
+         memset (&qval->n_value[n1->n_len],0,scale);
+         memcpy (qval->n_value, n1->n_value,
+                 n1->n_len + MIN(n1->n_scale,scale));
+         bc_free_num (quot);
+         *quot = qval;
+       }
+    }
+
+  /* Set up the divide.  Move the decimal point on n1 by n2's scale.
+     Remember, zeros on the end of num2 are wasted effort for dividing. */
+  scale2 = n2->n_scale;
+  n2ptr = (unsigned char *) n2->n_value+n2->n_len+scale2-1;
+  while ((scale2 > 0) && (*n2ptr-- == 0)) scale2--;
+
+  len1 = n1->n_len + scale2;
+  scale1 = n1->n_scale - scale2;
+  if (scale1 < scale)
+    extra = scale - scale1;
+  else
+    extra = 0;
+  num1 = (unsigned char *) malloc (n1->n_len+n1->n_scale+extra+2);
+  if (num1 == NULL) bc_out_of_memory();
+  memset (num1, 0, n1->n_len+n1->n_scale+extra+2);
+  memcpy (num1+1, n1->n_value, n1->n_len+n1->n_scale);
+
+  len2 = n2->n_len + scale2;
+  num2 = (unsigned char *) malloc (len2+1);
+  if (num2 == NULL) bc_out_of_memory();
+  memcpy (num2, n2->n_value, len2);
+  *(num2+len2) = 0;
+  n2ptr = num2;
+  while (*n2ptr == 0)
+    {
+      n2ptr++;
+      len2--;
+    }
+
+  /* Calculate the number of quotient digits. */
+  if (len2 > len1+scale)
+    {
+      qdigits = scale+1;
+      zero = TRUE;
+    }
+  else
+    {
+      zero = FALSE;
+      if (len2>len1)
+       qdigits = scale+1;      /* One for the zero integer part. */
+      else
+       qdigits = len1-len2+scale+1;
+    }
+
+  /* Allocate and zero the storage for the quotient. */
+  qval = bc_new_num (qdigits-scale,scale);
+  memset (qval->n_value, 0, qdigits);
+
+  /* Allocate storage for the temporary storage mval. */
+  mval = (unsigned char *) malloc (len2+1);
+  if (mval == NULL) bc_out_of_memory ();
+
+  /* Now for the full divide algorithm. */
+  if (!zero)
+    {
+      /* Normalize */
+      norm =  10 / ((int)*n2ptr + 1);
+      if (norm != 1)
+       {
+         _one_mult (num1, len1+scale1+extra+1, norm, num1);
+         _one_mult (n2ptr, len2, norm, n2ptr);
+       }
+
+      /* Initialize divide loop. */
+      qdig = 0;
+      if (len2 > len1)
+       qptr = (unsigned char *) qval->n_value+len2-len1;
+      else
+       qptr = (unsigned char *) qval->n_value;
+
+      /* Loop */
+      while (qdig <= len1+scale-len2)
+       {
+         /* Calculate the quotient digit guess. */
+         if (*n2ptr == num1[qdig])
+           qguess = 9;
+         else
+           qguess = (num1[qdig]*10 + num1[qdig+1]) / *n2ptr;
+
+         /* Test qguess. */
+         if (n2ptr[1]*qguess >
+             (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10
+              + num1[qdig+2])
+           {
+             qguess--;
+             /* And again. */
+             if (n2ptr[1]*qguess >
+                 (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10
+                 + num1[qdig+2])
+               qguess--;
+           }
+
+         /* Multiply and subtract. */
+         borrow = 0;
+         if (qguess != 0)
+           {
+             *mval = 0;
+             _one_mult (n2ptr, len2, qguess, mval+1);
+             ptr1 = (unsigned char *) num1+qdig+len2;
+             ptr2 = (unsigned char *) mval+len2;
+             for (count = 0; count < len2+1; count++)
+               {
+                 val = (int) *ptr1 - (int) *ptr2-- - borrow;
+                 if (val < 0)
+                   {
+                     val += 10;
+                     borrow = 1;
+                   }
+                 else
+                   borrow = 0;
+                 *ptr1-- = val;
+               }
+           }
+
+         /* Test for negative result. */
+         if (borrow == 1)
+           {
+             qguess--;
+             ptr1 = (unsigned char *) num1+qdig+len2;
+             ptr2 = (unsigned char *) n2ptr+len2-1;
+             carry = 0;
+             for (count = 0; count < len2; count++)
+               {
+                 val = (int) *ptr1 + (int) *ptr2-- + carry;
+                 if (val > 9)
+                   {
+                     val -= 10;
+                     carry = 1;
+                   }
+                 else
+                   carry = 0;
+                 *ptr1-- = val;
+               }
+             if (carry == 1) *ptr1 = (*ptr1 + 1) % 10;
+           }
+
+         /* We now know the quotient digit. */
+         *qptr++ =  qguess;
+         qdig++;
+       }
+    }
+
+  /* Clean up and return the number. */
+  qval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );
+  if (bc_is_zero (qval)) qval->n_sign = PLUS;
+  _bc_rm_leading_zeros (qval);
+  bc_free_num (quot);
+  *quot = qval;
+
+  /* Clean up temporary storage. */
+  free (mval);
+  free (num1);
+  free (num2);
+
+  return 0;    /* Everything is OK. */
+}
+
+
+/* Division *and* modulo for numbers.  This computes both NUM1 / NUM2 and
+   NUM1 % NUM2  and puts the results in QUOT and REM, except that if QUOT
+   is NULL then that store will be omitted.
+ */
+
+int
+bc_divmod (num1, num2, quot, rem, scale)
+     bc_num num1, num2, *quot, *rem;
+     int scale;
+{
+  bc_num quotient = NULL;
+  bc_num temp;
+  int rscale;
+
+  /* Check for correct numbers. */
+  if (bc_is_zero (num2)) return -1;
+
+  /* Calculate final scale. */
+  rscale = MAX (num1->n_scale, num2->n_scale+scale);
+  bc_init_num(&temp);
+
+  /* Calculate it. */
+  bc_divide (num1, num2, &temp, scale);
+  if (quot)
+    quotient = bc_copy_num (temp);
+  bc_multiply (temp, num2, &temp, rscale);
+  bc_sub (num1, temp, rem, rscale);
+  bc_free_num (&temp);
+
+  if (quot)
+    {
+      bc_free_num (quot);
+      *quot = quotient;
+    }
+
+  return 0;    /* Everything is OK. */
+}
+
+
+/* Modulo for numbers.  This computes NUM1 % NUM2  and puts the
+   result in RESULT.   */
+
+int
+bc_modulo (num1, num2, result, scale)
+     bc_num num1, num2, *result;
+     int scale;
+{
+  return bc_divmod (num1, num2, NULL, result, scale);
+}
+
+/* Raise BASE to the EXPO power, reduced modulo MOD.  The result is
+   placed in RESULT.  If a EXPO is not an integer,
+   only the integer part is used.  */
+
+int
+bc_raisemod (base, expo, mod, result, scale)
+     bc_num base, expo, mod, *result;
+     int scale;
+{
+  bc_num power, exponent, parity, temp;
+  int rscale;
+
+  /* Check for correct numbers. */
+  if (bc_is_zero(mod)) return -1;
+  if (bc_is_neg(expo)) return -1;
+
+  /* Set initial values.  */
+  power = bc_copy_num (base);
+  exponent = bc_copy_num (expo);
+  temp = bc_copy_num (_one_);
+  bc_init_num(&parity);
+
+  /* Check the base for scale digits. */
+  if (base->n_scale != 0)
+      bc_rt_warn ("non-zero scale in base");
+
+  /* Check the exponent for scale digits. */
+  if (exponent->n_scale != 0)
+    {
+      bc_rt_warn ("non-zero scale in exponent");
+      bc_divide (exponent, _one_, &exponent, 0); /*truncate */
+    }
+
+  /* Check the modulus for scale digits. */
+  if (mod->n_scale != 0)
+      bc_rt_warn ("non-zero scale in modulus");
+
+  /* Do the calculation. */
+  rscale = MAX(scale, base->n_scale);
+  while ( !bc_is_zero(exponent) )
+    {
+      (void) bc_divmod (exponent, _two_, &exponent, &parity, 0);
+      if ( !bc_is_zero(parity) )
+       {
+         bc_multiply (temp, power, &temp, rscale);
+         (void) bc_modulo (temp, mod, &temp, scale);
+       }
+
+      bc_multiply (power, power, &power, rscale);
+      (void) bc_modulo (power, mod, &power, scale);
+    }
+
+  /* Assign the value. */
+  bc_free_num (&power);
+  bc_free_num (&exponent);
+  bc_free_num (result);
+  *result = temp;
+  return 0;    /* Everything is OK. */
+}
+
+/* Raise NUM1 to the NUM2 power.  The result is placed in RESULT.
+   Maximum exponent is LONG_MAX.  If a NUM2 is not an integer,
+   only the integer part is used.  */
+
+void
+bc_raise (num1, num2, result, scale)
+     bc_num num1, num2, *result;
+     int scale;
+{
+   bc_num temp, power;
+   long exponent;
+   int rscale;
+   int pwrscale;
+   int calcscale;
+   char neg;
+
+   /* Check the exponent for scale digits and convert to a long. */
+   if (num2->n_scale != 0)
+     bc_rt_warn ("non-zero scale in exponent");
+   exponent = bc_num2long (num2);
+   if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0))
+       bc_rt_error ("exponent too large in raise");
+
+   /* Special case if exponent is a zero. */
+   if (exponent == 0)
+     {
+       bc_free_num (result);
+       *result = bc_copy_num (_one_);
+       return;
+     }
+
+   /* Other initializations. */
+   if (exponent < 0)
+     {
+       neg = TRUE;
+       exponent = -exponent;
+       rscale = scale;
+     }
+   else
+     {
+       neg = FALSE;
+       rscale = MIN (num1->n_scale*exponent, MAX(scale, num1->n_scale));
+     }
+
+   /* Set initial value of temp.  */
+   power = bc_copy_num (num1);
+   pwrscale = num1->n_scale;
+   while ((exponent & 1) == 0)
+     {
+       pwrscale = 2*pwrscale;
+       bc_multiply (power, power, &power, pwrscale);
+       exponent = exponent >> 1;
+     }
+   temp = bc_copy_num (power);
+   calcscale = pwrscale;
+   exponent = exponent >> 1;
+
+   /* Do the calculation. */
+   while (exponent > 0)
+     {
+       pwrscale = 2*pwrscale;
+       bc_multiply (power, power, &power, pwrscale);
+       if ((exponent & 1) == 1) {
+        calcscale = pwrscale + calcscale;
+        bc_multiply (temp, power, &temp, calcscale);
+       }
+       exponent = exponent >> 1;
+     }
+
+   /* Assign the value. */
+   if (neg)
+     {
+       bc_divide (_one_, temp, result, rscale);
+       bc_free_num (&temp);
+     }
+   else
+     {
+       bc_free_num (result);
+       *result = temp;
+       if ((*result)->n_scale > rscale)
+        (*result)->n_scale = rscale;
+     }
+   bc_free_num (&power);
+}
+
+/* Take the square root NUM and return it in NUM with SCALE digits
+   after the decimal place. */
+
+int
+bc_sqrt (num, scale)
+     bc_num *num;
+     int scale;
+{
+  int rscale, cmp_res, done;
+  int cscale;
+  bc_num guess, guess1, point5, diff;
+
+  /* Initial checks. */
+  cmp_res = bc_compare (*num, _zero_);
+  if (cmp_res < 0)
+    return 0;          /* error */
+  else
+    {
+      if (cmp_res == 0)
+       {
+         bc_free_num (num);
+         *num = bc_copy_num (_zero_);
+         return 1;
+       }
+    }
+  cmp_res = bc_compare (*num, _one_);
+  if (cmp_res == 0)
+    {
+      bc_free_num (num);
+      *num = bc_copy_num (_one_);
+      return 1;
+    }
+
+  /* Initialize the variables. */
+  rscale = MAX (scale, (*num)->n_scale);
+  bc_init_num(&guess);
+  bc_init_num(&guess1);
+  bc_init_num(&diff);
+  point5 = bc_new_num (1,1);
+  point5->n_value[1] = 5;
+
+
+  /* Calculate the initial guess. */
+  if (cmp_res < 0)
+    {
+      /* The number is between 0 and 1.  Guess should start at 1. */
+      guess = bc_copy_num (_one_);
+      cscale = (*num)->n_scale;
+    }
+  else
+    {
+      /* The number is greater than 1.  Guess should start at 10^(exp/2). */
+      bc_int2num (&guess,10);
+
+      bc_int2num (&guess1,(*num)->n_len);
+      bc_multiply (guess1, point5, &guess1, 0);
+      guess1->n_scale = 0;
+      bc_raise (guess, guess1, &guess, 0);
+      bc_free_num (&guess1);
+      cscale = 3;
+    }
+
+  /* Find the square root using Newton's algorithm. */
+  done = FALSE;
+  while (!done)
+    {
+      bc_free_num (&guess1);
+      guess1 = bc_copy_num (guess);
+      bc_divide (*num, guess, &guess, cscale);
+      bc_add (guess, guess1, &guess, 0);
+      bc_multiply (guess, point5, &guess, cscale);
+      bc_sub (guess, guess1, &diff, cscale+1);
+      if (bc_is_near_zero (diff, cscale))
+       {
+         if (cscale < rscale+1)
+           cscale = MIN (cscale*3, rscale+1);
+         else
+           done = TRUE;
+       }
+    }
+
+  /* Assign the number and clean up. */
+  bc_free_num (num);
+  bc_divide (guess,_one_,num,rscale);
+  bc_free_num (&guess);
+  bc_free_num (&guess1);
+  bc_free_num (&point5);
+  bc_free_num (&diff);
+  return 1;
+}
+
+
+/* The following routines provide output for bcd numbers package
+   using the rules of POSIX bc for output. */
+
+/* This structure is used for saving digits in the conversion process. */
+typedef struct stk_rec {
+       long  digit;
+       struct stk_rec *next;
+} stk_rec;
+
+/* The reference string for digits. */
+static char ref_str[] = "0123456789ABCDEF";
+
+
+/* A special output routine for "multi-character digits."  Exactly
+   SIZE characters must be output for the value VAL.  If SPACE is
+   non-zero, we must output one space before the number.  OUT_CHAR
+   is the actual routine for writing the characters. */
+
+void
+bc_out_long (val, size, space, out_char)
+     long val;
+     int size, space;
+#ifdef __STDC__
+     void (*out_char)(int);
+#else
+     void (*out_char)();
+#endif
+{
+  char digits[40];
+  int len, ix;
+
+  if (space) (*out_char) (' ');
+  sprintf (digits, "%ld", val);
+  len = strlen (digits);
+  while (size > len)
+    {
+      (*out_char) ('0');
+      size--;
+    }
+  for (ix=0; ix < len; ix++)
+    (*out_char) (digits[ix]);
+}
+
+/* Output of a bcd number.  NUM is written in base O_BASE using OUT_CHAR
+   as the routine to do the actual output of the characters. */
+
+void
+bc_out_num (num, o_base, out_char, leading_zero)
+     bc_num num;
+     int o_base;
+#ifdef __STDC__
+     void (*out_char)(int);
+#else
+     void (*out_char)();
+#endif
+     int leading_zero;
+{
+  char *nptr;
+  int  ix, fdigit, pre_space;
+  stk_rec *digits, *temp;
+  bc_num int_part, frac_part, base, cur_dig, t_num, max_o_digit;
+
+  /* The negative sign if needed. */
+  if (num->n_sign == MINUS) (*out_char) ('-');
+
+  /* Output the number. */
+  if (bc_is_zero (num))
+    (*out_char) ('0');
+  else
+    if (o_base == 10)
+      {
+       /* The number is in base 10, do it the fast way. */
+       nptr = num->n_value;
+       if (num->n_len > 1 || *nptr != 0)
+         for (ix=num->n_len; ix>0; ix--)
+           (*out_char) (BCD_CHAR(*nptr++));
+       else
+         nptr++;
+
+       if (leading_zero && bc_is_zero (num))
+         (*out_char) ('0');
+
+       /* Now the fraction. */
+       if (num->n_scale > 0)
+         {
+           (*out_char) ('.');
+           for (ix=0; ix<num->n_scale; ix++)
+             (*out_char) (BCD_CHAR(*nptr++));
+         }
+      }
+    else
+      {
+       /* special case ... */
+       if (leading_zero && bc_is_zero (num))
+         (*out_char) ('0');
+
+       /* The number is some other base. */
+       digits = NULL;
+       bc_init_num (&int_part);
+       bc_divide (num, _one_, &int_part, 0);
+       bc_init_num (&frac_part);
+       bc_init_num (&cur_dig);
+       bc_init_num (&base);
+       bc_sub (num, int_part, &frac_part, 0);
+       /* Make the INT_PART and FRAC_PART positive. */
+       int_part->n_sign = PLUS;
+       frac_part->n_sign = PLUS;
+       bc_int2num (&base, o_base);
+       bc_init_num (&max_o_digit);
+       bc_int2num (&max_o_digit, o_base-1);
+
+
+       /* Get the digits of the integer part and push them on a stack. */
+       while (!bc_is_zero (int_part))
+         {
+           bc_modulo (int_part, base, &cur_dig, 0);
+           temp = (stk_rec *) malloc (sizeof(stk_rec));
+           if (temp == NULL) bc_out_of_memory();
+           temp->digit = bc_num2long (cur_dig);
+           temp->next = digits;
+           digits = temp;
+           bc_divide (int_part, base, &int_part, 0);
+         }
+
+       /* Print the digits on the stack. */
+       if (digits != NULL)
+         {
+           /* Output the digits. */
+           while (digits != NULL)
+             {
+               temp = digits;
+               digits = digits->next;
+               if (o_base <= 16)
+                 (*out_char) (ref_str[ (int) temp->digit]);
+               else
+                 bc_out_long (temp->digit, max_o_digit->n_len, 1, out_char);
+               free (temp);
+             }
+         }
+
+       /* Get and print the digits of the fraction part. */
+       if (num->n_scale > 0)
+         {
+           (*out_char) ('.');
+           pre_space = 0;
+           t_num = bc_copy_num (_one_);
+           while (t_num->n_len <= num->n_scale) {
+             bc_multiply (frac_part, base, &frac_part, num->n_scale);
+             fdigit = bc_num2long (frac_part);
+             bc_int2num (&int_part, fdigit);
+             bc_sub (frac_part, int_part, &frac_part, 0);
+             if (o_base <= 16)
+               (*out_char) (ref_str[fdigit]);
+             else {
+               bc_out_long (fdigit, max_o_digit->n_len, pre_space, out_char);
+               pre_space = 1;
+             }
+             bc_multiply (t_num, base, &t_num, 0);
+           }
+           bc_free_num (&t_num);
+         }
+
+       /* Clean up. */
+       bc_free_num (&int_part);
+       bc_free_num (&frac_part);
+       bc_free_num (&base);
+       bc_free_num (&cur_dig);
+       bc_free_num (&max_o_digit);
+      }
+}
+/* Convert a number NUM to a long.  The function returns only the integer
+   part of the number.  For numbers that are too large to represent as
+   a long, this function returns a zero.  This can be detected by checking
+   the NUM for zero after having a zero returned. */
+
+long
+bc_num2long (num)
+     bc_num num;
+{
+  long val;
+  char *nptr;
+  int  i;
+
+  /* Extract the int value, ignore the fraction. */
+  val = 0;
+  nptr = num->n_value;
+  for (i=num->n_len; (i>0) && (val<=(LONG_MAX/BASE)); i--)
+    val = val*BASE + *nptr++;
+
+  /* Check for overflow.  If overflow, return zero. */
+  if (i>0) val = 0;
+  if (val < 0) val = 0;
+
+  /* Return the value. */
+  if (num->n_sign == PLUS)
+    return (val);
+  else
+    return (-val);
+}
+
+
+/* Convert an integer VAL to a bc number NUM. */
+
+void
+bc_int2num (num, val)
+     bc_num *num;
+     int val;
+{
+  char buffer[30];
+  char *bptr, *vptr;
+  int  ix = 1;
+  char neg = 0;
+
+  /* Sign. */
+  if (val < 0)
+    {
+      neg = 1;
+      val = -val;
+    }
+
+  /* Get things going. */
+  bptr = buffer;
+  *bptr++ = val % BASE;
+  val = val / BASE;
+
+  /* Extract remaining digits. */
+  while (val != 0)
+    {
+      *bptr++ = val % BASE;
+      val = val / BASE;
+      ix++;            /* Count the digits. */
+    }
+
+  /* Make the number. */
+  bc_free_num (num);
+  *num = bc_new_num (ix, 0);
+  if (neg) (*num)->n_sign = MINUS;
+
+  /* Assign the digits. */
+  vptr = (*num)->n_value;
+  while (ix-- > 0)
+    *vptr++ = *--bptr;
+}
+
+/* Convert a numbers to a string.  Base 10 only.*/
+
+char
+*bc_num2str (num)
+      bc_num num;
+{
+  char *str, *sptr;
+  char *nptr;
+  int  i, signch;
+
+  /* Allocate the string memory. */
+  signch = ( num->n_sign == PLUS ? 0 : 1 );  /* Number of sign chars. */
+  if (num->n_scale > 0)
+    str = (char *) malloc (num->n_len + num->n_scale + 2 + signch);
+  else
+    str = (char *) malloc (num->n_len + 1 + signch);
+  if (str == NULL) bc_out_of_memory();
+
+  /* The negative sign if needed. */
+  sptr = str;
+  if (signch) *sptr++ = '-';
+
+  /* Load the whole number. */
+  nptr = num->n_value;
+  for (i=num->n_len; i>0; i--)
+    *sptr++ = BCD_CHAR(*nptr++);
+
+  /* Now the fraction. */
+  if (num->n_scale > 0)
+    {
+      *sptr++ = '.';
+      for (i=0; i<num->n_scale; i++)
+       *sptr++ = BCD_CHAR(*nptr++);
+    }
+
+  /* Terminate the string and return it! */
+  *sptr = '\0';
+  return (str);
+}
+/* Convert strings to bc numbers.  Base 10 only.*/
+
+void
+bc_str2num (num, str, scale)
+     bc_num *num;
+     char *str;
+     int scale;
+{
+  int digits, strscale;
+  char *ptr, *nptr;
+  char zero_int;
+
+  /* Prepare num. */
+  bc_free_num (num);
+
+  /* Check for valid number and count digits. */
+  ptr = str;
+  digits = 0;
+  strscale = 0;
+  zero_int = FALSE;
+  if ( (*ptr == '+') || (*ptr == '-'))  ptr++;  /* Sign */
+  while (*ptr == '0') ptr++;                   /* Skip leading zeros. */
+  while (isdigit((int)*ptr)) ptr++, digits++;  /* digits */
+  if (*ptr == '.') ptr++;                      /* decimal point */
+  while (isdigit((int)*ptr)) ptr++, strscale++;        /* digits */
+  if ((*ptr != '\0') || (digits+strscale == 0))
+    {
+      *num = bc_copy_num (_zero_);
+      return;
+    }
+
+  /* Adjust numbers and allocate storage and initialize fields. */
+  strscale = MIN(strscale, scale);
+  if (digits == 0)
+    {
+      zero_int = TRUE;
+      digits = 1;
+    }
+  *num = bc_new_num (digits, strscale);
+
+  /* Build the whole number. */
+  ptr = str;
+  if (*ptr == '-')
+    {
+      (*num)->n_sign = MINUS;
+      ptr++;
+    }
+  else
+    {
+      (*num)->n_sign = PLUS;
+      if (*ptr == '+') ptr++;
+    }
+  while (*ptr == '0') ptr++;                   /* Skip leading zeros. */
+  nptr = (*num)->n_value;
+  if (zero_int)
+    {
+      *nptr++ = 0;
+      digits = 0;
+    }
+  for (;digits > 0; digits--)
+    *nptr++ = CH_VAL(*ptr++);
+
+
+  /* Build the fractional part. */
+  if (strscale > 0)
+    {
+      ptr++;  /* skip the decimal point! */
+      for (;strscale > 0; strscale--)
+       *nptr++ = CH_VAL(*ptr++);
+    }
+}
+
+/* Debugging routines */
+
+#ifdef DEBUG
+
+/* pn prints the number NUM in base 10. */
+
+static void
+out_char (int c)
+{
+  putchar(c);
+}
+
+
+void
+pn (num)
+     bc_num num;
+{
+  bc_out_num (num, 10, out_char, 0);
+  out_char ('\n');
+}
+
+
+/* pv prints a character array as if it was a string of bcd digits. */
+void
+pv (name, num, len)
+     char *name;
+     unsigned char *num;
+     int len;
+{
+  int i;
+  printf ("%s=", name);
+  for (i=0; i<len; i++) printf ("%c",BCD_CHAR(num[i]));
+  printf ("\n");
+}
+
+#endif
diff --git a/lib/testmul.c b/lib/testmul.c
new file mode 100644 (file)
index 0000000..ac33cc4
--- /dev/null
@@ -0,0 +1,246 @@
+/* compute the crossover for recursive and simple multiplication */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "number.h"
+#ifndef VARARGS
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/* from number.c ... */
+extern int mul_base_digits;
+/* extern int mul_small_digits; */
+extern bc_num _one_;
+
+/* global variables */
+int test_n = 1000;
+long test_time = 30 * CLOCKS_PER_SEC;  /* 30 seconds */ 
+
+/* Other things for number.c. */
+int std_only;
+
+void
+out_of_memory()
+{
+  fprintf (stderr, "Fatal error: Out of memory for malloc.\n");
+  exit (1);
+}
+
+/* Runtime error will  print a message and stop the machine. */
+
+#ifndef VARARGS
+#ifdef __STDC__
+void
+rt_error (char *mesg, ...)
+#else
+void
+rt_error (mesg)
+     char *mesg;
+#endif
+#else
+void
+rt_error (mesg, va_alist)
+     char *mesg;
+#endif
+{
+  va_list args;
+  char error_mesg [255];
+
+#ifndef VARARGS   
+  va_start (args, mesg);
+#else
+  va_start (args);
+#endif
+  vsprintf (error_mesg, mesg, args);
+  va_end (args);
+  
+  fprintf (stderr, "Runtime error: %s\n", error_mesg);
+}
+
+/* A runtime warning tells of some action taken by the processor that
+   may change the program execution but was not enough of a problem
+   to stop the execution. */
+
+#ifndef VARARGS
+#ifdef __STDC__
+void
+rt_warn (char *mesg, ...)
+#else
+void
+rt_warn (mesg)
+     char *mesg;
+#endif
+#else
+void
+rt_warn (mesg, va_alist)
+     char *mesg;
+#endif
+{
+  va_list args;
+  char error_mesg [255];
+
+#ifndef VARARGS   
+  va_start (args, mesg);
+#else
+  va_start (args);
+#endif
+  vsprintf (error_mesg, mesg, args);
+  va_end (args);
+
+  fprintf (stderr, "Runtime warning: %s\n", error_mesg);
+}
+
+void
+out_char (int ch)
+{
+  putchar (ch);
+}
+
+/* Time stuff !!! */
+
+int
+timeit ( bc_num a, bc_num b, int *n)
+{
+  clock_t first;
+  int i, res;
+  bc_num c;
+
+  bc_init_num (&c);
+  first = clock();
+  *n = 0;
+  do {
+    for (i=0; i<test_n; i++)
+      bc_multiply(a,b,&c,0);
+    *n += test_n;
+     res = (int) (clock() - first);
+  } while (res < test_time);
+  return res;
+}
+
+int debug = 0;  /* Print debugging messages? */
+
+int main (int argc, char **argv)
+{
+  bc_num ten, num, expo, big;
+
+  int min, max, mid;
+
+#if 0
+  int smallsize;
+#endif
+
+  int n1, n2;
+  clock_t t1, t2;
+  float permul1, permul2;
+
+  /* args? */
+  if (argc > 1)
+    if (strcmp (argv[1], "-d") == 0)
+      debug = 1;
+
+  bc_init_numbers();
+  bc_init_num (&ten);
+  bc_init_num (&num);
+  bc_init_num (&expo);
+  bc_init_num (&big);
+  bc_int2num (&ten, 10);
+
+  if (debug)
+    fprintf (stderr, "Timings are for %d multiplies\n"
+                    "Minimum time is %lu seconds\n", test_n,
+            test_time/CLOCKS_PER_SEC);
+
+  /* Two of the same size */
+  min = 10;
+  max = 500;
+
+  if (debug)
+    fprintf (stderr, "Testing numbers of the same length.\n");
+
+  while (min < max) {
+    mid = (min+max)/2;
+    if (debug) fprintf (stderr,"Checking %d...\n", mid);
+
+    bc_int2num (&expo, mid);
+    bc_raise (ten, expo, &num, 0);
+    bc_sub (num, _one_, &num, 0);
+
+    mul_base_digits = 2*mid+1;
+    t1 = timeit (num, num, &n1);
+    permul1 = (float)t1/(float)n1;
+
+    mul_base_digits = 2*mid-1;
+    t2 = timeit (num, num, &n2);
+    permul2 = (float)t2/(float)n2;
+
+    if (permul1 < permul2)
+      min = mid+1;
+    else
+      max = mid-1;
+
+    if (debug) {
+      fprintf (stderr, "n1 = %d :: n2 = %d\n", n1, n2);
+      fprintf (stderr, "p1 = %f :: p2 = %f\n", permul1, permul2);
+    }
+  }  
+
+  if (debug)
+    fprintf (stderr, "Base digits crossover at %d digits\n", min);
+  printf ("#define MUL_BASE_DIGITS %d\n", 2*min);
+
+
+#if 0
+  mul_base_digits = min;
+
+  /* Small one times a big one. */
+
+  smallsize = min/2;
+  bc_int2num (&expo, smallsize);
+  bc_raise (ten, expo, &big, 0);
+  bc_sub (num, _one_, &big, 0);
+
+  min = min / 2;
+  max = 500;
+
+  if (debug)
+    fprintf (stderr, "Testing numbers of the different length.\n");
+
+  while (min < max) {
+    mid = (min+max)/2;
+    if (debug) fprintf (stderr, "Checking %d...\n", mid);
+
+    bc_int2num (&expo, mid-smallsize);
+    bc_raise (ten, expo, &num, 0);
+    bc_sub (num, _one_, &num, 0);
+
+    mul_small_digits = mid+1;
+    t1 = timeit (big, num, &n1);
+    permul1 = (float)t1/(float)n1;
+
+    mul_small_digits = mid-1;
+    t2 = timeit (big, num, &n2);
+    permul2 = (float)t2/(float)n2;
+
+    if (permul1 < permul2)
+      min = mid+1;
+    else
+      max = mid-1;
+
+    if (debug) {
+      fprintf (stderr, "n1 = %d :: n2 = %d\n", n1, n2);
+      fprintf (stderr, "p1 = %f :: p2 = %f\n", permul1, permul2);
+    }
+  }  
+  
+  if (debug)
+    fprintf (stderr, "Non equal digits crossover at %d total digits\n", min);
+  printf ("#define MUL_SMALL_DIGITS = %d\n", min);
+
+#endif
+
+  return 0;
+}
diff --git a/lib/vfprintf.c b/lib/vfprintf.c
new file mode 100644 (file)
index 0000000..ad53d0c
--- /dev/null
@@ -0,0 +1,31 @@
+/* vfprintf.c -- this was provided for minix.  It may not
+   work on any other system. */
+
+#include "config.h"
+#ifndef HAVE_VPRINTF
+#ifndef HAVE_DOPRINT
+ #error need vfprintf() or doprint()
+#else
+
+#ifdef HAVE_LIB_H
+#include <lib.h>
+#endif
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+int vfprintf(file, format, argp)
+FILE *file;
+_CONST char *format;
+va_list argp;
+{
+  _doprintf(file, format, argp);
+  if (testflag(file, PERPRINTF)) fflush(file);
+  return 0;
+}
+
+#endif /* HAVE_DOPRINT */
+#endif /* !HAVE_VFPRINTF */
diff --git a/missing b/missing
new file mode 100755 (executable)
index 0000000..894e786
--- /dev/null
+++ b/missing
@@ -0,0 +1,360 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2005-06-08.21
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+  lex|yacc)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+          sed 's/\.am$/.in/' |
+          while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo "#! /bin/sh"
+       echo "# Created by GNU Automake missing as a replacement of"
+       echo "#  $ $@"
+       echo "exit 0"
+       chmod +x $file
+       exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.y)
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.c
+           fi
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.h
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f y.tab.h ]; then
+       echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+       echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.l)
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" lex.yy.c
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+       echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+        you modified a dependency of a manual page.  You may need the
+        \`Help2man' package in order for those modifications to take
+        effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+       file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo ".ab help2man is required to generate this page"
+       exit 1
+    fi
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+       case "$firstarg" in
+       *o*)
+           firstarg=`echo "$firstarg" | sed s/o//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+       case "$firstarg" in
+       *h*)
+           firstarg=`echo "$firstarg" | sed s/h//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/packaging/bc-1.06-dc_ibase.patch b/packaging/bc-1.06-dc_ibase.patch
new file mode 100644 (file)
index 0000000..7d5fa20
--- /dev/null
@@ -0,0 +1,58 @@
+--- bc-1.06/dc/numeric.c.dc_ibase      2007-08-22 08:37:57.000000000 +0200
++++ bc-1.06/dc/numeric.c       2007-08-22 08:37:40.000000000 +0200
+@@ -285,6 +285,8 @@ dc_getnum DC_DECLARG((input, ibase, read
+       int             digit;
+       int             decimal;
+       int             c;
++      int             c_buff = 0;
++      int             multi = 0;
+       bc_init_num(&tmp);
+       bc_init_num(&build);
+@@ -302,6 +304,9 @@ dc_getnum DC_DECLARG((input, ibase, read
+       }
+       while (isspace(c))
+               c = (*input)();
++      c_buff = (*input)();    
++      if (isdigit(c_buff) || ('A' <= c_buff && c_buff <= 'F') || c_buff == '.')
++                      multi = 1;              
+       for (;;){
+               if (isdigit(c))
+                       digit = c - '0';
+@@ -309,10 +314,15 @@ dc_getnum DC_DECLARG((input, ibase, read
+                       digit = 10 + c - 'A';
+               else
+                       break;
+-              c = (*input)();
++              digit = multi ? (digit >= ibase ? ibase -1 : digit) : digit;
+               bc_int2num(&tmp, digit);
+               bc_multiply(result, base, &result, 0);
+               bc_add(result, tmp, &result, 0);
++              if (c_buff) {
++                      c = c_buff;
++                      c_buff = 0;
++              } else
++                      c = (*input)();
+       }
+       if (c == '.'){
+               bc_free_num(&build);
+@@ -321,13 +331,18 @@ dc_getnum DC_DECLARG((input, ibase, read
+               build = bc_copy_num(_zero_);
+               decimal = 0;
+               for (;;){
+-                      c = (*input)();
++                      if (c_buff) {
++                              c = c_buff;
++                              c_buff = 0;
++                      } else
++                              c = (*input)();
+                       if (isdigit(c))
+                               digit = c - '0';
+                       else if ('A' <= c && c <= 'F')
+                               digit = 10 + c - 'A';
+                       else
+                               break;
++                      digit = digit >= ibase ? ibase -1 : digit;
+                       bc_int2num(&tmp, digit);
+                       bc_multiply(build, base, &build, 0);
+                       bc_add(build, tmp, &build, 0);
diff --git a/packaging/bc-1.06.95-matlib.patch b/packaging/bc-1.06.95-matlib.patch
new file mode 100644 (file)
index 0000000..796c5e2
--- /dev/null
@@ -0,0 +1,20 @@
+diff -urNp bc-1.06.95-orig/bc/storage.c bc-1.06.95/bc/storage.c
+--- bc-1.06.95-orig/bc/storage.c       2006-09-05 04:39:31.000000000 +0200
++++ bc-1.06.95/bc/storage.c    2010-12-22 10:26:43.805250912 +0100
+@@ -99,6 +99,7 @@ more_functions (VOID)
+     {
+       f = &functions[indx];
+       f->f_defined = FALSE;
++      f->f_void = FALSE;
+       f->f_body = (char *) bc_malloc (BC_START_SIZE);
+       f->f_body_size = BC_START_SIZE;
+       f->f_code_size = 0;
+@@ -179,7 +180,7 @@ more_arrays ()
+   /* Initialize the new elements. */
+-  for (; indx < v_count; indx++)
++  for (; indx < a_count; indx++)
+     arrays[indx] = NULL;
+   /* Free the old elements. */
diff --git a/packaging/bc-1.06.95-memleak.patch b/packaging/bc-1.06.95-memleak.patch
new file mode 100644 (file)
index 0000000..0b8fc5b
--- /dev/null
@@ -0,0 +1,26 @@
+diff --git a/bc/bc.y b/bc/bc.y
+index 14dc4be..bd91c38 100644
+--- a/bc/bc.y
++++ b/bc/bc.y
+@@ -569,6 +569,7 @@ expression         :  named_expression ASSIGN_OP
+                                   generate (">");
+                                 break;
+                               }
++                            free($2);
+                           }
+                       | expression '+' expression
+                           {
+diff --git a/bc/util.c b/bc/util.c
+index 30beaf9..26e2e85 100644
+--- a/bc/util.c
++++ b/bc/util.c
+@@ -602,8 +602,7 @@ lookup (name, namekind)
+     case FUNCTDEF:
+       if (id->f_name != 0)
+       {
+-        if (namekind != FUNCT)
+-          free(name);
++        free(name);
+         /* Check to see if we are redefining a math lib function. */ 
+         if (use_math && namekind == FUNCTDEF && id->f_name <= 6)
+           id->f_name = next_func++;
diff --git a/packaging/bc-1.06.95-sigintmasking.patch b/packaging/bc-1.06.95-sigintmasking.patch
new file mode 100644 (file)
index 0000000..c86340f
--- /dev/null
@@ -0,0 +1,27 @@
+Binary files bc-1.06.95-orig/dc/.dc.c.swp and bc-1.06.95/dc/.dc.c.swp differ
+diff -urNp bc-1.06.95-orig/dc/eval.c bc-1.06.95/dc/eval.c
+--- bc-1.06.95-orig/dc/eval.c  2006-06-04 13:04:40.000000000 +0200
++++ bc-1.06.95/dc/eval.c       2011-09-08 15:11:48.815060585 +0200
+@@ -661,7 +661,9 @@ dc_evalfile DC_DECLARG((fp))
+       int next_negcmp = 0;
+       dc_data datum;
+-      signal(SIGINT, dc_trap_interrupt);
++    /* Do not mask SIGINT when running from stdin */
++      if (fp != stdin)
++      signal(SIGINT, dc_trap_interrupt);
+       stdin_lookahead = EOF;
+       for (c=getc(fp); c!=EOF; c=peekc){
+               peekc = getc(fp);
+diff -urNp bc-1.06.95-orig/doc/dc.texi bc-1.06.95/doc/dc.texi
+--- bc-1.06.95-orig/doc/dc.texi        2006-06-11 10:15:54.000000000 +0200
++++ bc-1.06.95/doc/dc.texi     2011-09-08 15:09:37.032059798 +0200
+@@ -126,6 +126,8 @@ To exit, use @samp{q}.
+ (or whatever other keystroke your system uses to generate a @code{SIGINT})
+ does not exit;
+ it is used to abort macros that are looping, etc.
++This is not true if running on stdin to prevent accidental user confusion
++about @kbd{C-c} unfunctionality.
+ A reverse-polish calculator stores numbers on a stack.
+ Entering a number pushes it on the stack.
diff --git a/packaging/bc.spec b/packaging/bc.spec
new file mode 100644 (file)
index 0000000..78f97c8
--- /dev/null
@@ -0,0 +1,69 @@
+Summary: GNU's bc (a numeric processing language) and dc (a calculator)
+Name: bc
+Version: 1.06.95
+Release: 6%{?dist}
+License: GPLv2+
+URL: http://www.gnu.org/software/bc/
+Group: Applications/Engineering
+Source: ftp://alpha.gnu.org/pub/gnu/bc/bc-%{version}.tar.bz2
+Patch1: bc-1.06-dc_ibase.patch
+Patch2: bc-1.06.95-memleak.patch
+Patch3: bc-1.06.95-matlib.patch
+Patch4: bc-1.06.95-sigintmasking.patch
+Requires(post): /sbin/install-info
+Requires(preun): /sbin/install-info
+BuildRequires: readline-devel, flex, bison, texinfo
+
+%description
+The bc package includes bc and dc. Bc is an arbitrary precision
+numeric processing arithmetic language. Dc is an interactive
+arbitrary precision stack based calculator, which can be used as a
+text mode calculator.
+
+Install the bc package if you need its number handling capabilities or
+if you would like to use its text mode calculator.
+
+%prep
+%setup -q
+%patch1 -p1 -b .dc_ibase
+%patch2 -p1 -b .memleak
+%patch3 -p1 -b .matlib
+%patch4 -p1 -b .sigintmask
+
+%build
+%configure --with-readline
+make %{?_smp_mflags}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+
+make install DESTDIR=$RPM_BUILD_ROOT
+rm -f $RPM_BUILD_ROOT/%{_infodir}/dir
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+if [ -e %{_infodir}/bc.info.gz -a -e %{_infodir}/dc.info.gz ]; then
+  /sbin/install-info %{_infodir}/bc.info.gz %{_infodir}/dir \
+  --entry="* bc: (bc).                      The GNU calculator language." || :
+  /sbin/install-info %{_infodir}/dc.info.gz %{_infodir}/dir \
+  --entry="* dc: (dc).                      The GNU RPN calculator." || :
+fi
+
+%preun
+if [ $1 = 0 -a -e %{_infodir}/bc.info.gz -a -e %{_infodir}/dc.info.gz ]; then
+  /sbin/install-info --delete %{_infodir}/bc.info.gz %{_infodir}/dir \
+  --entry="* bc: (bc).                      The GNU calculator language." || :
+  /sbin/install-info --delete %{_infodir}/dc.info.gz %{_infodir}/dir \
+  --entry="* dc: (dc).                      The GNU RPN calculator." || :
+fi
+
+%files
+%defattr(-,root,root,-)
+%doc COPYING COPYING.LIB FAQ AUTHORS NEWS README Examples/
+%{_bindir}/dc
+%{_bindir}/bc
+%{_mandir}/*/*
+%{_infodir}/*
+