aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Klemm <andreas@FreeBSD.org>1998-04-29 21:53:01 +0000
committerAndreas Klemm <andreas@FreeBSD.org>1998-04-29 21:53:01 +0000
commit17f33912d7d23882f1b856a5ea1adf6b5fe40390 (patch)
tree1529c15b522fa7bd199b5491bc88817aefc9b779
downloadsrc-17f33912d7d23882f1b856a5ea1adf6b5fe40390.tar.gz
src-17f33912d7d23882f1b856a5ea1adf6b5fe40390.zip
Import GNU bc 1.04vendor/misc-GNU/bc/1.0.4
PR: 4183
Notes
Notes: svn path=/vendor/bc/dist/; revision=35516 svn path=/vendor/bc/1.0.4/; revision=35518; tag=vendor/misc-GNU/bc/1.0.4
-rw-r--r--contrib/bc/AUTHORS4
-rw-r--r--contrib/bc/COPYING341
-rw-r--r--contrib/bc/ChangeLog694
-rw-r--r--contrib/bc/Examples/ckbook.b16
-rw-r--r--contrib/bc/Examples/pi.b53
-rw-r--r--contrib/bc/Examples/primes.b32
-rw-r--r--contrib/bc/Examples/twins.b40
-rw-r--r--contrib/bc/INSTALL176
-rw-r--r--contrib/bc/Makefile.am9
-rw-r--r--contrib/bc/Makefile.in296
-rw-r--r--contrib/bc/NEWS31
-rw-r--r--contrib/bc/README57
-rw-r--r--contrib/bc/Test/BUG.bc40
-rw-r--r--contrib/bc/Test/TESTS.bc565
-rw-r--r--contrib/bc/Test/array.b14
-rw-r--r--contrib/bc/Test/arrayp.b30
-rw-r--r--contrib/bc/Test/aryprm.b16
-rw-r--r--contrib/bc/Test/atan.b5
-rw-r--r--contrib/bc/Test/checklib.b109
-rw-r--r--contrib/bc/Test/div.b8
-rw-r--r--contrib/bc/Test/exp.b3
-rw-r--r--contrib/bc/Test/fact.b13
-rw-r--r--contrib/bc/Test/jn.b6
-rw-r--r--contrib/bc/Test/ln.b3
-rw-r--r--contrib/bc/Test/mul.b7
-rw-r--r--contrib/bc/Test/raise.b3
-rw-r--r--contrib/bc/Test/signum87
-rw-r--r--contrib/bc/Test/sine.b5
-rw-r--r--contrib/bc/Test/sqrt.b13
-rw-r--r--contrib/bc/Test/sqrt1.b13
-rw-r--r--contrib/bc/Test/sqrt2.b10
-rw-r--r--contrib/bc/Test/testfn.b47
-rwxr-xr-xcontrib/bc/Test/timetest14
-rw-r--r--contrib/bc/acconfig.h15
-rw-r--r--contrib/bc/aclocal.m4100
-rw-r--r--contrib/bc/bc/Makefile.am46
-rw-r--r--contrib/bc/bc/Makefile.in294
-rw-r--r--contrib/bc/bc/bc.c1808
-rw-r--r--contrib/bc/bc/bc.h42
-rw-r--r--contrib/bc/bc/bc.y637
-rw-r--r--contrib/bc/bc/execute.c786
-rwxr-xr-xcontrib/bc/bc/fix-libmath_h8
-rw-r--r--contrib/bc/bc/global.c42
-rw-r--r--contrib/bc/bc/libmath.b279
-rw-r--r--contrib/bc/bc/libmath.h40
-rw-r--r--contrib/bc/bc/load.c348
-rw-r--r--contrib/bc/bc/main.c323
-rw-r--r--contrib/bc/bc/sbc.y446
-rw-r--r--contrib/bc/bc/scan.c1612
-rw-r--r--contrib/bc/bc/scan.l293
-rw-r--r--contrib/bc/bc/storage.c1070
-rw-r--r--contrib/bc/bc/util.c859
-rw-r--r--contrib/bc/config.h.in68
-rwxr-xr-xcontrib/bc/configure2315
-rw-r--r--contrib/bc/configure.in69
-rw-r--r--contrib/bc/dc/Makefile.am10
-rw-r--r--contrib/bc/dc/Makefile.in250
-rw-r--r--contrib/bc/dc/array.c108
-rw-r--r--contrib/bc/dc/dc-proto.h83
-rw-r--r--contrib/bc/dc/dc-regdef.h40
-rw-r--r--contrib/bc/dc/dc.c173
-rw-r--r--contrib/bc/dc/dc.h78
-rw-r--r--contrib/bc/dc/eval.c646
-rw-r--r--contrib/bc/dc/misc.c177
-rw-r--r--contrib/bc/dc/numeric.c536
-rw-r--r--contrib/bc/dc/stack.c457
-rw-r--r--contrib/bc/dc/string.c208
-rw-r--r--contrib/bc/doc/Makefile.am10
-rw-r--r--contrib/bc/doc/Makefile.in280
-rw-r--r--contrib/bc/doc/bc.1787
-rw-r--r--contrib/bc/doc/dc.1436
-rw-r--r--contrib/bc/doc/dc.texi497
-rw-r--r--contrib/bc/doc/texinfo.tex4506
-rw-r--r--contrib/bc/h/bcdefs.h166
-rw-r--r--contrib/bc/h/const.h101
-rw-r--r--contrib/bc/h/getopt.h133
-rw-r--r--contrib/bc/h/global.h147
-rw-r--r--contrib/bc/h/number.h65
-rw-r--r--contrib/bc/h/proto.h171
-rw-r--r--contrib/bc/h/version.h29
-rwxr-xr-xcontrib/bc/install-sh238
-rw-r--r--contrib/bc/lib/Makefile.am9
-rw-r--r--contrib/bc/lib/Makefile.in230
-rw-r--r--contrib/bc/lib/getopt.c752
-rw-r--r--contrib/bc/lib/getopt1.c184
-rw-r--r--contrib/bc/lib/number.c1565
-rw-r--r--contrib/bc/lib/vfprintf.c31
-rwxr-xr-xcontrib/bc/missing134
-rwxr-xr-xcontrib/bc/mkinstalldirs36
-rw-r--r--contrib/bc/stamp-h.in1
90 files changed, 27534 insertions, 0 deletions
diff --git a/contrib/bc/AUTHORS b/contrib/bc/AUTHORS
new file mode 100644
index 000000000000..c78d68f108e1
--- /dev/null
+++ b/contrib/bc/AUTHORS
@@ -0,0 +1,4 @@
+Phil Nelson <phil@cs.wwu.edu> wrote bc, including the number.c
+source in the "lib" directory.
+
+Ken Pizzini wrote dc.
diff --git a/contrib/bc/COPYING b/contrib/bc/COPYING
new file mode 100644
index 000000000000..86cf81acb8c6
--- /dev/null
+++ b/contrib/bc/COPYING
@@ -0,0 +1,341 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The 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.
+
+ 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.)
+
+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.
+
+ 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.
+
+ 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
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to 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) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+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) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+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/contrib/bc/ChangeLog b/contrib/bc/ChangeLog
new file mode 100644
index 000000000000..24898b113a3a
--- /dev/null
+++ b/contrib/bc/ChangeLog
@@ -0,0 +1,694 @@
+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/contrib/bc/Examples/ckbook.b b/contrib/bc/Examples/ckbook.b
new file mode 100644
index 000000000000..5815ea02075c
--- /dev/null
+++ b/contrib/bc/Examples/ckbook.b
@@ -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/contrib/bc/Examples/pi.b b/contrib/bc/Examples/pi.b
new file mode 100644
index 000000000000..0d840cf795ee
--- /dev/null
+++ b/contrib/bc/Examples/pi.b
@@ -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/contrib/bc/Examples/primes.b b/contrib/bc/Examples/primes.b
new file mode 100644
index 000000000000..2b52ca7e3f8e
--- /dev/null
+++ b/contrib/bc/Examples/primes.b
@@ -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/contrib/bc/Examples/twins.b b/contrib/bc/Examples/twins.b
new file mode 100644
index 000000000000..de910a793125
--- /dev/null
+++ b/contrib/bc/Examples/twins.b
@@ -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/contrib/bc/INSTALL b/contrib/bc/INSTALL
new file mode 100644
index 000000000000..3b50ea95726f
--- /dev/null
+++ b/contrib/bc/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/contrib/bc/Makefile.am b/contrib/bc/Makefile.am
new file mode 100644
index 000000000000..cbdde44da097
--- /dev/null
+++ b/contrib/bc/Makefile.am
@@ -0,0 +1,9 @@
+## Process this file with automake to produce Makefile.in
+SUBDIRS = lib bc dc doc
+
+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
diff --git a/contrib/bc/Makefile.in b/contrib/bc/Makefile.in
new file mode 100644
index 000000000000..9a4e2071946f
--- /dev/null
+++ b/contrib/bc/Makefile.in
@@ -0,0 +1,296 @@
+# Makefile.in generated automatically by automake 1.1n from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = true
+PRE_INSTALL = true
+POST_INSTALL = true
+NORMAL_UNINSTALL = true
+PRE_UNINSTALL = true
+POST_UNINSTALL = true
+CC = @CC@
+LEX = @LEX@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+
+SUBDIRS = lib bc dc doc
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+CONFIG_HEADER_IN = config.h.in
+CONFIG_HEADER_FULL = config.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
+Makefile.in NEWS acconfig.h aclocal.m4 config.h.in configure \
+configure.in install-sh missing mkinstalldirs stamp-h.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+default: all
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(srcdir)/aclocal.m4: configure.in
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: configure
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+$(CONFIG_HEADER): stamp-h
+stamp-h: $(CONFIG_HEADER_IN) $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=$(CONFIG_HEADER_FULL) \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h
+$(srcdir)/$(CONFIG_HEADER_IN): stamp-h.in
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
+ cd $(top_srcdir) && $(AUTOHEADER)
+ echo timestamp > $(srcdir)/stamp-h.in
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ rm -f $(CONFIG_HEADER)
+
+maintainer-clean-hdr:
+
+# 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.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @for subdir in $(SUBDIRS); do \
+ target=`echo $@ | sed s/-recursive//`; \
+ echo "Making $$target in $$subdir"; \
+ (cd $$subdir && $(MAKE) $$target) \
+ || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ (cd $$subdir && $(MAKE) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES)
+ here=`pwd` && cd $(srcdir) && mkid -f$$here/ID $(SOURCES) $(HEADERS)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ done; \
+ test -z "$(ETAGS_ARGS)config.h.in$(SOURCES)$(HEADERS)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $(SOURCES) $(HEADERS) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+# 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
+ rm -rf $(distdir)
+ GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) \
+ && $(MAKE) dvi \
+ && $(MAKE) check \
+ && $(MAKE) install \
+ && $(MAKE) installcheck \
+ && $(MAKE) dist
+ rm -rf $(distdir)
+ @echo "========================"; \
+ echo "$(distdir).tar.gz is ready for distribution"; \
+ echo "========================"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ rm -rf $(distdir)
+distdir: $(DISTFILES)
+ rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 755 $(distdir)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done
+ for subdir in $(SUBDIRS); do \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 755 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ done
+ $(MAKE) distdir="$(distdir)" dist-hook
+info: info-recursive
+dvi: dvi-recursive
+check: all-am
+ $(MAKE) check-recursive
+installcheck: installcheck-recursive
+all-recursive-am: $(CONFIG_HEADER)
+ $(MAKE) all-recursive
+
+all-am: Makefile config.h
+
+install-exec: install-exec-recursive
+ @$(NORMAL_INSTALL)
+
+install-data: install-data-recursive
+ @$(NORMAL_INSTALL)
+
+install: install-recursive
+ @:
+
+uninstall: uninstall-recursive
+
+all: all-recursive-am all-am
+
+install-strip:
+ $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
+installdirs: installdirs-recursive
+
+
+mostlyclean-generic:
+ test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ rm -f Makefile $(DISTCLEANFILES)
+ rm -f config.cache config.log stamp-h
+ test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+ test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic
+
+clean-am: clean-hdr clean-tags clean-generic mostlyclean-am
+
+distclean-am: distclean-hdr distclean-tags distclean-generic clean-am
+
+maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+
+mostlyclean: mostlyclean-recursive mostlyclean-am
+
+clean: clean-recursive clean-am
+
+distclean: distclean-recursive distclean-am
+ rm -f config.status
+
+maintainer-clean: maintainer-clean-recursive maintainer-clean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f config.status
+
+.PHONY: default mostlyclean-hdr distclean-hdr clean-hdr \
+maintainer-clean-hdr install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info dvi \
+installcheck all-recursive-am all-am install-exec install-data install \
+uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
+
+
+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
+
+# 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/contrib/bc/NEWS b/contrib/bc/NEWS
new file mode 100644
index 000000000000..aae74d15bcb1
--- /dev/null
+++ b/contrib/bc/NEWS
@@ -0,0 +1,31 @@
+This is GNU bc version 1.04. (And dc version 1.0.4)
+
+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/contrib/bc/README b/contrib/bc/README
new file mode 100644
index 000000000000..7bc2315f0330
--- /dev/null
+++ b/contrib/bc/README
@@ -0,0 +1,57 @@
+-------- 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/contrib/bc/Test/BUG.bc b/contrib/bc/Test/BUG.bc
new file mode 100644
index 000000000000..254eefe68f59
--- /dev/null
+++ b/contrib/bc/Test/BUG.bc
@@ -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/contrib/bc/Test/TESTS.bc b/contrib/bc/Test/TESTS.bc
new file mode 100644
index 000000000000..ec42172a422b
--- /dev/null
+++ b/contrib/bc/Test/TESTS.bc
@@ -0,0 +1,565 @@
+From phil@cs.wwu.edu Mon Mar 20 23:13:22 1995
+Date: Mon, 20 Mar 1995 23:12:17 -0800
+From: Phil Nelson <phil@cs.wwu.edu>
+To: phil@steelhead.cs.wwu.edu
+Subject: [jhn@ironwood.cray.com: XPG4 bc(1) failures]
+
+From: jhn@ironwood.cray.com (James Nordby)
+Subject: XPG4 bc(1) failures
+To: phil@cs.wwu.edu
+Date: Fri, 17 Mar 1995 12:14:13 -0600 (CST)
+X-Mailer: ELM [version 2.4 PL24-CRI-b]
+Mime-Version: 1.0
+Content-Type: text/plain; charset=US-ASCII
+Content-Transfer-Encoding: 7bit
+Content-Length: 14277
+
+
+Phil,
+
+Here are the test results I'm getting from the XPG4 test suite,
+with some explanation and fixes so far. Let me know what you
+think...
+
+Thanks much,
+Jim Nordby (jhn@cray.com)
+
+
+-------- bc 08:38:34 --------
+
+Assertion #20 (A): bc reads text files
+Expected exit code = 0; Received 139
+Standard output isn't the same as file 'bc_eso_20_1'
+diff of "out.stdout" and "bc_eso_20_1":
+*** out.stdout Fri Mar 17 08:39:22 1995
+--- bc_eso_20_1 Fri Mar 17 08:39:22 1995
+***************
+*** 0 ****
+--- 1,31 ----
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 11111111111111111111111111111111111111111111111111111111111111111111
++ 1111111
+Assertion Result: FAIL
+
+I couldn't reproduce this problem; when I rebuilt your bc and
+ran it, I got a different problem with printing out a large
+number. The XPG4 tests expected lines to be 70 characters
+long, INCLUDING the newline (this comes from the POSIX definition
+of a line). To fix it, I changed util.c like so:
+
+*** util.c Thu Mar 16 10:47:36 1995
+--- util.c.old Thu Mar 16 10:50:10 1995
+***************
+*** 309,323 ****
+ else
+ {
+ out_col++;
+- #ifdef _CRAY
+- /*
+- * XPG4 considers a line to include the <newline>;
+- * therefore we want 68 numerals, <backslash>, <newline>
+- */
+- if (out_col == 69)
+- #else
+ if (out_col == 70)
+- #endif
+ {
+ putchar ('\\');
+ putchar ('\n');
+--- 309,315 ----
+
+
+
+
+
+
+Assertion #42 (A): check reserved words
+Standard error isn't empty
+Contents of out.stderr:
+(standard_in) 6: syntax error
+(standard_in) 15: syntax error
+Standard output isn't the same as file 'bc_eso_42_1'
+diff of "out.stdout" and "bc_eso_42_1":
+*** out.stdout Fri Mar 17 08:39:43 1995
+--- bc_eso_42_1 Fri Mar 17 08:39:43 1995
+***************
+*** 1,2 ****
+--- 1,3 ----
+ 2
+ 1
++ 0
+Assertion Result: FAIL
+
+This one is debatable, based on the grammar in the POSIX manual.
+Here's the input file:
+
+cat << \VSC-EOF > input
+define a() {
+ auto b;
+ for ( b = 0; b < 10; b++ ) {
+ b;
+ if ( b == 1 )
+ break;
+ }
+ return ( 5 ) ;
+}
+ibase = 10;
+length ( obase );
+scale = 0;
+sqrt(1);
+while ( a() != 5 )
+VSC-EOF
+
+They want these constructs to be accepted:
+
+
+if (b == 1)
+ whatever;
+for (x = 0; x < 10; x++)
+ whatever;
+while (x < 10)
+ whatever;
+
+rather than just
+
+if (b == 1) {
+ whatever
+}
+etc.
+
+The grammar as it's currently worded requires a '{' before hitting
+a NEWLINE for these constructs. It's easy enough to change in bc.y
+(see below), but if I do change it, it still barfs on the last
+line of the file ( 'while (a() != 5)' ). Since the while lacks
+a body, it gives a syntax error; they're expecting a '0' to be
+returned. The grammar could be changed to support this, but is
+it a good idea?
+
+
+*** bc.y Thu Mar 16 10:47:20 1995
+--- bc.y.old Thu Mar 16 10:50:11 1995
+***************
+*** 142,150 ****
+ | error statement
+ { $$ = $2; }
+ ;
+- allow_newlines : /* empty */
+- | NEWLINE allow_newlines
+- ;
+ statement : Warranty
+ { warranty (""); }
+ | Limits
+--- 142,147 ----
+***************
+*** 231,237 ****
+ sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
+ generate (genstr);
+ }
+! allow_newlines statement
+ {
+ sprintf (genstr, "J%1d:N%1d:",
+ continue_label, break_label);
+--- 228,234 ----
+ sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
+ generate (genstr);
+ }
+! statement
+ {
+ sprintf (genstr, "J%1d:N%1d:",
+ continue_label, break_label);
+***************
+*** 246,252 ****
+ sprintf (genstr, "Z%1d:", if_label);
+ generate (genstr);
+ }
+! allow_newlines statement opt_else
+ {
+ sprintf (genstr, "N%1d:", if_label);
+ generate (genstr);
+--- 243,249 ----
+ sprintf (genstr, "Z%1d:", if_label);
+ generate (genstr);
+ }
+! statement opt_else
+ {
+ sprintf (genstr, "N%1d:", if_label);
+ generate (genstr);
+***************
+*** 265,271 ****
+ sprintf (genstr, "Z%1d:", break_label);
+ generate (genstr);
+ }
+! ')' allow_newlines statement
+ {
+ sprintf (genstr, "J%1d:N%1d:", $1, break_label);
+ generate (genstr);
+--- 262,268 ----
+ sprintf (genstr, "Z%1d:", break_label);
+ generate (genstr);
+ }
+! ')' statement
+ {
+ sprintf (genstr, "J%1d:N%1d:", $1, break_label);
+ generate (genstr);
+
+
+
+
+Assertion #49 (A): check strings
+Expected exit code = 0; Received 1
+Standard error isn't empty
+Contents of out.stderr:
+File (NULL) is unavailable.
+Standard output isn't the same as file 'bc_eso_49_1'
+diff of "out.stdout" and "bc_eso_49_1":
+cmd-1794 diff: Missing newline at end of file 'bc_eso_49_1'.
+*** out.stdout Fri Mar 17 08:40:01 1995
+--- bc_eso_49_1 Fri Mar 17 08:40:01 1995
+***************
+*** 0 ****
+--- 1 ----
++ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+*LINE CONTINUATION -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+*LINE CONTINUATION -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+Assertion Result: FAIL
+
+This gist of this is that the standard expects numbers to
+be truncated to 70 characters, but STRINGS should not.
+My changes to fix this are:
+
+
+*** execute.c Thu Mar 16 13:06:39 1995
+--- execute.c.old Thu Mar 16 10:50:09 1995
+***************
+*** 208,218 ****
+ case 'O' : /* Write a string to the output with processing. */
+ while ((ch = byte(&pc)) != '"')
+ if (ch != '\\')
+- #ifdef _CRAY
+- putchar (ch);
+- #else
+ out_char (ch);
+- #endif
+ else
+ {
+ ch = byte(&pc);
+--- 207,213 ----
+***************
+*** 219,234 ****
+ if (ch == '"') break;
+ switch (ch)
+ {
+- #ifdef _CRAY
+- case 'a': putchar (007); break;
+- case 'b': putchar ('\b'); break;
+- case 'f': putchar ('\f'); break;
+- case 'n': putchar ('\n'); break;
+- case 'q': putchar ('"'); break;
+- case 'r': putchar ('\r'); break;
+- case 't': putchar ('\t'); break;
+- case '\\': putchar ('\\'); break;
+- #else
+ case 'a': out_char (007); break;
+ case 'b': out_char ('\b'); break;
+ case 'f': out_char ('\f'); break;
+--- 214,219 ----
+***************
+*** 237,243 ****
+ case 'r': out_char ('\r'); break;
+ case 't': out_char ('\t'); break;
+ case '\\': out_char ('\\'); break;
+- #endif
+ default: break;
+ }
+ }
+--- 222,227 ----
+***************
+*** 350,360 ****
+ break;
+
+ case 'w' : /* Write a string to the output. */
+- #ifdef _CRAY
+- while ((ch = byte(&pc)) != '"') putchar (ch);
+- #else
+ while ((ch = byte(&pc)) != '"') out_char (ch);
+- #endif
+ if (interactive) fflush (stdout);
+ break;
+
+
+
+
+Assertion #77 (C): output longer than 70 characters
+Standard output isn't the same as file 'bc_eso_77_1'
+diff of "out.stdout" and "bc_eso_77_1":
+*** out.stdout Fri Mar 17 08:41:13 1995
+--- bc_eso_77_1 Fri Mar 17 08:41:13 1995
+***************
+*** 1,2 ****
+! 3.3333333333333333333333333333333333333333333333333333333333333333333
+! 33333333333333333333333333333333
+--- 1,2 ----
+! 3.333333333333333333333333333333333333333333333333333333333333333333
+! 333333333333333333333333333333333
+Assertion Result: FAIL
+
+Same as assertion #20 above...
+
+
+
+
+Assertion #92 (A): check %
+Standard output isn't the same as file 'bc_eso_92_1'
+diff of "out.stdout" and "bc_eso_92_1":
+*** out.stdout Fri Mar 17 08:41:33 1995
+--- bc_eso_92_1 Fri Mar 17 08:41:33 1995
+***************
+*** 4,8 ****
+ 4
+ 15
+ 1
+! 0
+! 0
+--- 4,8 ----
+ 4
+ 15
+ 1
+! 6
+! 5
+Assertion Result: FAIL
+
+This one is a pain. The failing code looks like this:
+
+scale = 4
+scale ( 5.000000 % 2.0 )
+scale ( 5.00 % 2.0 )
+
+They expect '6' and '5' for output, instead of '0', based on
+the explanation of the modulus operator ("scale of the result
+shall be 'max(scale + scale(b), scale(a)'"), even though the
+result is a 0. I was able to fix this problem by the change
+below:
+
+*** number.c Thu Mar 16 13:15:43 1995
+--- number.c.old Thu Mar 16 10:50:09 1995
+***************
+*** 614,623 ****
+ case 0:
+ /* They are equal! return zero! */
+ diff = copy_num (_zero_);
+- #ifdef _CRAY
+- /* correct the scale here */
+- diff->n_scale = MAX (n1->n_scale, n2->n_scale);
+- #endif
+ break;
+ case 1:
+ /* n2 is less than n1, subtract n2 from n1. */
+
+but this causes another test failure that I haven't looked at.
+
+
+
+
+Assertion #130 (A): functions are call by value
+Standard output isn't the same as file 'bc_eso_130_1'
+diff of "out.stdout" and "bc_eso_130_1":
+*** out.stdout Fri Mar 17 08:42:24 1995
+--- bc_eso_130_1 Fri Mar 17 08:42:24 1995
+***************
+*** 4,10 ****
+ 5
+ 4
+ 0
+! 4
+ 3
+ 3
+ 5
+--- 4,10 ----
+ 5
+ 4
+ 0
+! 5
+ 3
+ 3
+ 5
+Assertion Result: FAIL
+
+Assertion #131 (A): functions are call by value
+Standard output isn't the same as file 'bc_eso_131_1'
+diff of "out.stdout" and "bc_eso_131_1":
+*** out.stdout Fri Mar 17 08:42:28 1995
+--- bc_eso_131_1 Fri Mar 17 08:42:28 1995
+***************
+*** 4,10 ****
+ 5
+ 4
+ 0
+! 4
+ 3
+ 3
+ 5
+--- 4,10 ----
+ 5
+ 4
+ 0
+! 5
+ 3
+ 3
+ 5
+Assertion Result: FAIL
+
+
+Both of these are the 'arrays are passed by value' problem.
+One of the test cases is below:
+
+cat << \VSC-EOF > bc_in_130_1
+a[0] = 3
+a[0]
+define b(a[]) {
+a[0]
+a[0] = 4
+a[0]
+}
+a[0]
+a[0] = 5
+a[0]
+b(a[])
+a[0]
+VSC-EOF
+
+They expect the assignment of a[0] inside the b() function
+to not affect a[0] outside of the function.
+
+
+
+
+
+Assertion #139 (A): check sin
+Standard output isn't the same as file 'bc_eso_139_1'
+diff of "out.stdout" and "bc_eso_139_1":
+*** out.stdout Fri Mar 17 08:42:40 1995
+--- bc_eso_139_1 Fri Mar 17 08:42:39 1995
+***************
+*** 1,5 ****
+ 0
+! 20
+ 1.68294196961579301330
+ 20
+ 1.6829419696
+--- 1,5 ----
+ 0
+! 0
+ 1.68294196961579301330
+ 20
+ 1.6829419696
+Assertion Result: FAIL
+
+Assertion #141 (A): check arctanngent
+Standard output isn't the same as file 'bc_eso_141_1'
+diff of "out.stdout" and "bc_eso_141_1":
+*** out.stdout Fri Mar 17 08:42:44 1995
+--- bc_eso_141_1 Fri Mar 17 08:42:44 1995
+***************
+*** 1,5 ****
+ 0
+! 20
+ 3.14159265358979323844
+ 20
+ 3.1415926532
+--- 1,5 ----
+ 0
+! 0
+ 3.14159265358979323844
+ 20
+ 3.1415926532
+Assertion Result: FAIL
+
+Assertion #142 (A): check log
+Standard output isn't the same as file 'bc_eso_142_1'
+diff of "out.stdout" and "bc_eso_142_1":
+*** out.stdout Fri Mar 17 08:42:47 1995
+--- bc_eso_142_1 Fri Mar 17 08:42:47 1995
+***************
+*** 1,5 ****
+ 0
+! 20
+ 2.30258509299404568401
+ 20
+ 2.3025850929
+--- 1,5 ----
+ 0
+! 0
+ 2.30258509299404568401
+ 20
+ 2.3025850929
+Assertion Result: FAIL
+
+Assertion #144 (A): check bessel
+Standard output isn't the same as file 'bc_eso_144_1'
+diff of "out.stdout" and "bc_eso_144_1":
+*** out.stdout Fri Mar 17 08:42:51 1995
+--- bc_eso_144_1 Fri Mar 17 08:42:51 1995
+***************
+*** 1,5 ****
+ 0
+! 20
+ .57672480775687338720
+ 20
+ .5767248077
+--- 1,5 ----
+ 0
+! 0
+ .57672480775687338720
+ 20
+ .5767248077
+Assertion Result: FAIL
+
+All of these are the same. I'll give you the test case
+for 'sin'; what they're expecting is 0:
+
+scale(s(0))
+
+bc outputs '20' (which is the scale at the time), but the
+interpretation of the standard says that it should be '0',
+since s(0) is 0, and the scale of 0 is 0. I think that
+this interpretation disagrees with one of the previous
+assertions (assertion #92).
+
+/* end of test results */
+
+
+
+--
+Phil Nelson
+e-mail: phil@cs.wwu.edu
+http://www.cs.wwu.edu/~phil
+
+
diff --git a/contrib/bc/Test/array.b b/contrib/bc/Test/array.b
new file mode 100644
index 000000000000..a0341ec7d748
--- /dev/null
+++ b/contrib/bc/Test/array.b
@@ -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/contrib/bc/Test/arrayp.b b/contrib/bc/Test/arrayp.b
new file mode 100644
index 000000000000..3f3ca505c958
--- /dev/null
+++ b/contrib/bc/Test/arrayp.b
@@ -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/contrib/bc/Test/aryprm.b b/contrib/bc/Test/aryprm.b
new file mode 100644
index 000000000000..9d3f95b8b8d4
--- /dev/null
+++ b/contrib/bc/Test/aryprm.b
@@ -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/contrib/bc/Test/atan.b b/contrib/bc/Test/atan.b
new file mode 100644
index 000000000000..e742279183c2
--- /dev/null
+++ b/contrib/bc/Test/atan.b
@@ -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/contrib/bc/Test/checklib.b b/contrib/bc/Test/checklib.b
new file mode 100644
index 000000000000..44c1facd7023
--- /dev/null
+++ b/contrib/bc/Test/checklib.b
@@ -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/contrib/bc/Test/div.b b/contrib/bc/Test/div.b
new file mode 100644
index 000000000000..3c7d377dca0b
--- /dev/null
+++ b/contrib/bc/Test/div.b
@@ -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/contrib/bc/Test/exp.b b/contrib/bc/Test/exp.b
new file mode 100644
index 000000000000..ed0e536384ca
--- /dev/null
+++ b/contrib/bc/Test/exp.b
@@ -0,0 +1,3 @@
+for (a=0; a<150; a++) x=e(a)
+x
+quit
diff --git a/contrib/bc/Test/fact.b b/contrib/bc/Test/fact.b
new file mode 100644
index 000000000000..8d1474702bdc
--- /dev/null
+++ b/contrib/bc/Test/fact.b
@@ -0,0 +1,13 @@
+define f (x) {
+
+ if (x<=1) return(1)
+ return (f(x-1)*x)
+}
+
+"Here we go"
+for (a=1; a<100; a++) b+=f(a)/a
+"
+"
+"b=";b
+quit
+
diff --git a/contrib/bc/Test/jn.b b/contrib/bc/Test/jn.b
new file mode 100644
index 000000000000..80ac915cc394
--- /dev/null
+++ b/contrib/bc/Test/jn.b
@@ -0,0 +1,6 @@
+scale = 30
+for (a=0; a<5; a=a+2) {
+ for (b=0; b<100; b=b+10) x=j(a,b)
+}
+x
+quit
diff --git a/contrib/bc/Test/ln.b b/contrib/bc/Test/ln.b
new file mode 100644
index 000000000000..00a1deb78181
--- /dev/null
+++ b/contrib/bc/Test/ln.b
@@ -0,0 +1,3 @@
+for (a=1; a<10000000000000000000000000000; a = a*2) x=l(a)
+x
+quit
diff --git a/contrib/bc/Test/mul.b b/contrib/bc/Test/mul.b
new file mode 100644
index 000000000000..1970ed131310
--- /dev/null
+++ b/contrib/bc/Test/mul.b
@@ -0,0 +1,7 @@
+scale = 20
+for (i=0; i<1000; i++) {
+ for (j=1; j<100; j++) b=i*j
+}
+b
+quit
+
diff --git a/contrib/bc/Test/raise.b b/contrib/bc/Test/raise.b
new file mode 100644
index 000000000000..a8858151999a
--- /dev/null
+++ b/contrib/bc/Test/raise.b
@@ -0,0 +1,3 @@
+for (i=0; i<1000; i++) a = 2^i;
+a
+quit
diff --git a/contrib/bc/Test/signum b/contrib/bc/Test/signum
new file mode 100644
index 000000000000..9e27d2ddb30d
--- /dev/null
+++ b/contrib/bc/Test/signum
@@ -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/contrib/bc/Test/sine.b b/contrib/bc/Test/sine.b
new file mode 100644
index 000000000000..18c4b575a3f7
--- /dev/null
+++ b/contrib/bc/Test/sine.b
@@ -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/contrib/bc/Test/sqrt.b b/contrib/bc/Test/sqrt.b
new file mode 100644
index 000000000000..3fb548c97ca7
--- /dev/null
+++ b/contrib/bc/Test/sqrt.b
@@ -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/contrib/bc/Test/sqrt1.b b/contrib/bc/Test/sqrt1.b
new file mode 100644
index 000000000000..c3ca2698fcc8
--- /dev/null
+++ b/contrib/bc/Test/sqrt1.b
@@ -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/contrib/bc/Test/sqrt2.b b/contrib/bc/Test/sqrt2.b
new file mode 100644
index 000000000000..bd0eaadb76c7
--- /dev/null
+++ b/contrib/bc/Test/sqrt2.b
@@ -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/contrib/bc/Test/testfn.b b/contrib/bc/Test/testfn.b
new file mode 100644
index 000000000000..7578fc5d45fd
--- /dev/null
+++ b/contrib/bc/Test/testfn.b
@@ -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/contrib/bc/Test/timetest b/contrib/bc/Test/timetest
new file mode 100755
index 000000000000..90da6ab7ad67
--- /dev/null
+++ b/contrib/bc/Test/timetest
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Time the functions.
+#
+BC=../bc
+SYSBC=/usr/bin/bc
+for file in exp.b ln.b sine.b atan.b jn.b mul.b div.b raise.b sqrt.b
+do
+for prog in $BC $SYSBC
+do
+echo Timing $file with $prog
+time $prog -l $file
+done
+done
diff --git a/contrib/bc/acconfig.h b/contrib/bc/acconfig.h
new file mode 100644
index 000000000000..ac625a5c91c4
--- /dev/null
+++ b/contrib/bc/acconfig.h
@@ -0,0 +1,15 @@
+/* PACKAGE name */
+#undef PACKAGE
+
+/* Package VERSION number */
+#undef VERSION
+
+/* define if the math lib is to be loaded from a file. */
+#undef BC_MATH_FILE
+
+/* Define to use the readline library. */
+#undef READLINE
+
+/* Define to `size_t' if <sys/types.h> and <stddef.h> don't define. */
+#undef ptrdiff_t
+
diff --git a/contrib/bc/aclocal.m4 b/contrib/bc/aclocal.m4
new file mode 100644
index 000000000000..16cedb131c68
--- /dev/null
+++ b/contrib/bc/aclocal.m4
@@ -0,0 +1,100 @@
+dnl aclocal.m4 generated automatically by aclocal 1.1n
+
+# Do all the work for Automake. 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.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AM_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION"))
+AM_SANITY_CHECK
+AC_ARG_PROGRAM
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_PROG_MAKE_SET])
+
+
+# serial 1
+
+AC_DEFUN(AM_PROG_INSTALL,
+[AC_REQUIRE([AC_PROG_INSTALL])
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+AC_SUBST(INSTALL_SCRIPT)dnl
+])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# 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 conftestfile 2> /dev/null`
+ if test "$@" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+if ($2 --version) > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl
+changequote([,]))])
+
diff --git a/contrib/bc/bc/Makefile.am b/contrib/bc/bc/Makefile.am
new file mode 100644
index 000000000000..82223d885a1c
--- /dev/null
+++ b/contrib/bc/bc/Makefile.am
@@ -0,0 +1,46 @@
+## 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
+
+EXTRA_DIST = bc.h fix-libmath_h libmath.b sbc.y
+noinst_HEADERS = libmath.h
+
+DISTCLEANFILES = sbc sbc.c sbc.h
+MAINTAINERCLEANFILES = libmath.h bc.c bc.h
+
+datadir = $(prefix)/@DATADIRNAME@
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../h
+LDADD = ../lib/libbc.a @LEXLIB@
+
+$(PROGRAMS): $(LDADD)
+
+scan.o: bc.h
+global.o: libmath.h
+
+libmath.h: libmath.b
+ echo \"\" > libmath.h
+ $(MAKE) fbc
+ ./fbc -c $(srcdir)/libmath.b </dev/null >libmath.h
+ $(srcdir)/fix-libmath_h
+ rm -f ./fbc
+
+install-data-local:
+ if grep -s "define BC_MATH_FILE" ../config.h; \
+ then $(mkinstalldirs) $(libdir); \
+ rm -f $(libdir)/libmath.b; \
+ $(INSTALL_DATA) $(srcdir)/libmath.b $(libdir); \
+ chmod 444 $(libdir)/libmath.b; \
+ else true; \
+ fi
+
+fbcOBJ = main.o bc.o scan.o execute.o global.o load.o storage.o util.o
+fbc: $(fbcOBJ)
+ $(LINK) $(fbcOBJ) $(LDADD) $(LIBS)
+
+
+sbcOBJ = main.o sbc.o scan.o execute.o global.o load.o storage.o util.o
+sbc.o: sbc.c
+sbc: $(sbcOBJ)
+ $(LINK) $(sbcOBJ) $(LDADD) $(LIBS)
diff --git a/contrib/bc/bc/Makefile.in b/contrib/bc/bc/Makefile.in
new file mode 100644
index 000000000000..f673c0d902d8
--- /dev/null
+++ b/contrib/bc/bc/Makefile.in
@@ -0,0 +1,294 @@
+# Makefile.in generated automatically by automake 1.1n from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = true
+PRE_INSTALL = true
+POST_INSTALL = true
+NORMAL_UNINSTALL = true
+PRE_UNINSTALL = true
+POST_UNINSTALL = true
+CC = @CC@
+LEX = @LEX@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+
+bin_PROGRAMS = bc
+
+bc_SOURCES = main.c bc.y scan.l execute.c load.c storage.c util.c global.c
+
+EXTRA_DIST = bc.h fix-libmath_h libmath.b sbc.y
+noinst_HEADERS = libmath.h
+
+DISTCLEANFILES = sbc sbc.c sbc.h
+MAINTAINERCLEANFILES = libmath.h bc.c bc.h
+
+datadir = $(prefix)/@DATADIRNAME@
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../h
+LDADD = ../lib/libbc.a @LEXLIB@
+
+fbcOBJ = main.o bc.o scan.o execute.o global.o load.o storage.o util.o
+
+sbcOBJ = main.o sbc.o scan.o execute.o global.o load.o storage.o util.o
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+bc_OBJECTS = main.o bc.o scan.o execute.o load.o storage.o util.o \
+global.o
+bc_LDADD = $(LDADD)
+bc_DEPENDENCIES = ../lib/libbc.a
+bc_LDFLAGS =
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LEXLIB = @LEXLIB@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(LDFLAGS) -o $@
+HEADERS = $(noinst_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in bc.c scan.c
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+SOURCES = $(bc_SOURCES)
+OBJECTS = $(bc_OBJECTS)
+
+default: all
+
+.SUFFIXES:
+.SUFFIXES: .c .o .y .l
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu bc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ $(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ rm -f *.o core
+
+clean-compile:
+
+distclean-compile:
+ rm -f *.tab.c
+
+maintainer-clean-compile:
+
+bc: $(bc_OBJECTS) $(bc_DEPENDENCIES)
+ @rm -f bc
+ $(LINK) $(bc_LDFLAGS) $(bc_OBJECTS) $(bc_LDADD) $(LIBS)
+.y.c:
+ $(YACC) $(YFLAGS) $< && mv y.tab.c $@
+ if test -f y.tab.h; then \
+ if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
+ else :; fi
+.l.c:
+ $(LEX) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES)
+ here=`pwd` && cd $(srcdir) && mkid -f$$here/ID $(SOURCES) $(HEADERS)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ done; \
+ test -z "$(ETAGS_ARGS)$(SOURCES)$(HEADERS)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $(SOURCES) $(HEADERS) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = bc
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done
+info:
+dvi:
+check: all
+ $(MAKE)
+installcheck:
+install-exec: install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+
+install-data: install-data-local
+ @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+ @:
+
+uninstall: uninstall-binPROGRAMS
+
+all: $(PROGRAMS) $(HEADERS) Makefile
+
+install-strip:
+ $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
+installdirs:
+ $(mkinstalldirs) $(bindir)
+
+
+mostlyclean-generic:
+ test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ rm -f Makefile $(DISTCLEANFILES)
+ rm -f config.cache config.log stamp-h
+ test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+ test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-tags mostlyclean-generic
+
+clean: clean-binPROGRAMS clean-compile clean-tags clean-generic \
+ mostlyclean
+
+distclean: distclean-binPROGRAMS distclean-compile distclean-tags \
+ distclean-generic clean
+ rm -f config.status
+
+maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \
+clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \
+install-binPROGRAMS mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info dvi installcheck \
+install-exec install-data install uninstall all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+$(PROGRAMS): $(LDADD)
+
+scan.o: bc.h
+global.o: libmath.h
+
+libmath.h: libmath.b
+ echo \"\" > libmath.h
+ $(MAKE) fbc
+ ./fbc -c $(srcdir)/libmath.b </dev/null >libmath.h
+ $(srcdir)/fix-libmath_h
+ rm -f ./fbc
+
+install-data-local:
+ if grep -s "define BC_MATH_FILE" ../config.h; \
+ then $(mkinstalldirs) $(libdir); \
+ rm -f $(libdir)/libmath.b; \
+ $(INSTALL_DATA) $(srcdir)/libmath.b $(libdir); \
+ chmod 444 $(libdir)/libmath.b; \
+ else true; \
+ fi
+fbc: $(fbcOBJ)
+ $(LINK) $(fbcOBJ) $(LDADD) $(LIBS)
+sbc.o: sbc.c
+sbc: $(sbcOBJ)
+ $(LINK) $(sbcOBJ) $(LDADD) $(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/contrib/bc/bc/bc.c b/contrib/bc/bc/bc.c
new file mode 100644
index 000000000000..e04bed2e8453
--- /dev/null
+++ b/contrib/bc/bc/bc.c
@@ -0,0 +1,1808 @@
+
+/* A Bison parser, made from bc.y
+ by GNU Bison version 1.25
+ */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define NEWLINE 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 Warranty 283
+#define Halt 284
+#define Last 285
+#define Continue 286
+#define Print 287
+#define Limits 288
+#define UNARY_MINUS 289
+#define History 290
+
+#line 1 "bc.y"
+
+/* bc.y: The grammar for a POSIX compatable bc processor with some
+ extensions to the language. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+#include "bcdefs.h"
+#include "global.h"
+#include "proto.h"
+
+#line 38 "bc.y"
+typedef union {
+ char *s_value;
+ char c_value;
+ int i_value;
+ arg_list *a_value;
+ } YYSTYPE;
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define YYFINAL 185
+#define YYFLAG -32768
+#define YYNTBASE 50
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 290 ? yytranslate[x] : 83)
+
+static const 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, 40, 2, 2, 43,
+ 44, 38, 36, 47, 37, 2, 39, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 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, 2, 2, 2, 2,
+ 48, 2, 49, 41, 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, 45, 2, 46, 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
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = { 0,
+ 0, 1, 4, 7, 9, 12, 13, 15, 16, 18,
+ 22, 25, 26, 28, 31, 35, 38, 42, 44, 47,
+ 49, 51, 53, 55, 57, 59, 61, 63, 65, 70,
+ 71, 72, 73, 74, 89, 90, 99, 100, 101, 110,
+ 114, 115, 119, 121, 125, 127, 129, 130, 131, 136,
+ 137, 150, 151, 153, 154, 158, 162, 164, 168, 173,
+ 177, 183, 190, 191, 193, 195, 199, 203, 209, 210,
+ 212, 213, 215, 216, 221, 222, 227, 228, 233, 236,
+ 240, 244, 248, 252, 256, 260, 264, 267, 269, 271,
+ 275, 280, 283, 286, 291, 296, 301, 305, 307, 312,
+ 314, 316, 318, 320
+};
+
+static const short yyrhs[] = { -1,
+ 50, 51, 0, 53, 3, 0, 69, 0, 1, 3,
+ 0, 0, 3, 0, 0, 55, 0, 53, 42, 55,
+ 0, 53, 42, 0, 0, 55, 0, 54, 3, 0,
+ 54, 3, 55, 0, 54, 42, 0, 54, 42, 56,
+ 0, 56, 0, 1, 56, 0, 28, 0, 33, 0,
+ 78, 0, 7, 0, 14, 0, 31, 0, 15, 0,
+ 29, 0, 17, 0, 17, 43, 77, 44, 0, 0,
+ 0, 0, 0, 18, 57, 43, 76, 42, 58, 76,
+ 42, 59, 76, 44, 60, 52, 56, 0, 0, 19,
+ 43, 78, 44, 61, 52, 56, 67, 0, 0, 0,
+ 20, 62, 43, 78, 63, 44, 52, 56, 0, 45,
+ 54, 46, 0, 0, 32, 64, 65, 0, 66, 0,
+ 66, 47, 65, 0, 7, 0, 78, 0, 0, 0,
+ 22, 68, 52, 56, 0, 0, 13, 8, 43, 71,
+ 44, 52, 45, 3, 72, 70, 54, 46, 0, 0,
+ 73, 0, 0, 26, 73, 3, 0, 26, 73, 42,
+ 0, 8, 0, 8, 48, 49, 0, 38, 8, 48,
+ 49, 0, 73, 47, 8, 0, 73, 47, 8, 48,
+ 49, 0, 73, 47, 38, 8, 48, 49, 0, 0,
+ 75, 0, 78, 0, 8, 48, 49, 0, 75, 47,
+ 78, 0, 75, 47, 8, 48, 49, 0, 0, 78,
+ 0, 0, 78, 0, 0, 82, 10, 79, 78, 0,
+ 0, 78, 4, 80, 78, 0, 0, 78, 5, 81,
+ 78, 0, 6, 78, 0, 78, 11, 78, 0, 78,
+ 36, 78, 0, 78, 37, 78, 0, 78, 38, 78,
+ 0, 78, 39, 78, 0, 78, 40, 78, 0, 78,
+ 41, 78, 0, 37, 78, 0, 82, 0, 9, 0,
+ 43, 78, 44, 0, 8, 43, 74, 44, 0, 12,
+ 82, 0, 82, 12, 0, 16, 43, 78, 44, 0,
+ 21, 43, 78, 44, 0, 23, 43, 78, 44, 0,
+ 27, 43, 44, 0, 8, 0, 8, 48, 78, 49,
+ 0, 24, 0, 25, 0, 23, 0, 35, 0, 30,
+ 0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+ 105, 114, 116, 118, 120, 126, 127, 130, 132, 133,
+ 134, 136, 138, 139, 140, 141, 142, 144, 145, 148,
+ 150, 152, 161, 168, 178, 189, 191, 193, 195, 197,
+ 202, 213, 224, 234, 242, 249, 255, 261, 268, 274,
+ 276, 279, 280, 281, 283, 289, 292, 293, 301, 302,
+ 316, 322, 324, 326, 328, 330, 333, 335, 337, 339,
+ 341, 343, 346, 348, 350, 355, 361, 366, 373, 378,
+ 380, 385, 391, 403, 418, 426, 431, 439, 447, 453,
+ 481, 486, 491, 496, 501, 506, 511, 516, 525, 541,
+ 543, 559, 578, 601, 603, 605, 607, 613, 615, 620,
+ 622, 624, 626, 630
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = { "$","error","$undefined.","NEWLINE",
+"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","Warranty","Halt","Last","Continue","Print","Limits","UNARY_MINUS",
+"History","'+'","'-'","'*'","'/'","'%'","'^'","';'","'('","')'","'{'","'}'",
+"','","'['","']'","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_parameter_list","opt_auto_define_list",
+"define_list","opt_argument_list","argument_list","opt_expression","return_expression",
+"expression","@11","@12","@13","named_expression", NULL
+};
+#endif
+
+static const short yyr1[] = { 0,
+ 50, 50, 51, 51, 51, 52, 52, 53, 53, 53,
+ 53, 54, 54, 54, 54, 54, 54, 55, 55, 56,
+ 56, 56, 56, 56, 56, 56, 56, 56, 56, 57,
+ 58, 59, 60, 56, 61, 56, 62, 63, 56, 56,
+ 64, 56, 65, 65, 66, 66, 67, 68, 67, 70,
+ 69, 71, 71, 72, 72, 72, 73, 73, 73, 73,
+ 73, 73, 74, 74, 75, 75, 75, 75, 76, 76,
+ 77, 77, 79, 78, 80, 78, 81, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 82, 82, 82,
+ 82, 82, 82, 82
+};
+
+static const short yyr2[] = { 0,
+ 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, 1, 4, 0,
+ 0, 0, 0, 14, 0, 8, 0, 0, 8, 3,
+ 0, 3, 1, 3, 1, 1, 0, 0, 4, 0,
+ 12, 0, 1, 0, 3, 3, 1, 3, 4, 3,
+ 5, 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, 1, 4, 1,
+ 1, 1, 1, 1
+};
+
+static const short yydefact[] = { 1,
+ 0, 0, 0, 23, 98, 89, 0, 0, 24, 26,
+ 0, 28, 30, 0, 37, 0, 102, 100, 101, 0,
+ 20, 27, 104, 25, 41, 21, 103, 0, 0, 0,
+ 2, 0, 9, 18, 4, 22, 88, 5, 19, 79,
+ 63, 0, 98, 102, 92, 0, 0, 71, 0, 0,
+ 0, 0, 0, 0, 0, 87, 0, 0, 0, 13,
+ 3, 0, 75, 77, 0, 0, 0, 0, 0, 0,
+ 0, 73, 93, 98, 0, 64, 65, 0, 52, 0,
+ 0, 72, 69, 0, 0, 0, 0, 97, 45, 42,
+ 43, 46, 90, 0, 16, 40, 10, 0, 0, 80,
+ 81, 82, 83, 84, 85, 86, 0, 0, 91, 0,
+ 99, 57, 0, 0, 53, 94, 29, 0, 70, 35,
+ 38, 95, 96, 0, 15, 17, 76, 78, 74, 66,
+ 98, 67, 0, 0, 6, 0, 31, 6, 0, 44,
+ 0, 58, 0, 7, 0, 60, 0, 69, 0, 6,
+ 68, 59, 0, 0, 0, 0, 47, 0, 54, 61,
+ 0, 32, 48, 36, 39, 0, 50, 62, 69, 6,
+ 0, 0, 0, 0, 55, 56, 0, 33, 49, 51,
+ 6, 0, 34, 0, 0
+};
+
+static const short yydefgoto[] = { 1,
+ 31, 145, 32, 59, 60, 34, 49, 148, 169, 181,
+ 138, 51, 139, 55, 90, 91, 164, 170, 35, 172,
+ 114, 167, 115, 75, 76, 118, 81, 36, 107, 98,
+ 99, 37
+};
+
+static const short yypact[] = {-32768,
+ 170, 375, 567,-32768, -37,-32768, 120, 15,-32768,-32768,
+ -38, -34,-32768, -28,-32768, -19, -16,-32768,-32768, -13,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, 567, 567, 213,
+-32768, 17,-32768,-32768,-32768, 642, 6,-32768,-32768, 442,
+ 597, 567, -9,-32768,-32768, -11, 567, 567, 39, 567,
+ 41, 567, 567, -4, 537,-32768, 122, 505, 16,-32768,
+-32768, 305,-32768,-32768, 567, 567, 567, 567, 567, 567,
+ 567,-32768,-32768, -36, 42, 43, 642, 40, 5, 410,
+ 44, 642, 567, 419, 567, 428, 466,-32768,-32768,-32768,
+ 45, 642,-32768, 259, 505,-32768,-32768, 567, 567, 404,
+ 34, 34, 46, 46, 46, 46, 567, 88,-32768, 627,
+-32768, 53, 83, 58, 56,-32768,-32768, 63, 642,-32768,
+ 642,-32768,-32768, 537,-32768,-32768, 442, -3, 404,-32768,
+ -26, 642, 57, 66, 113, 23,-32768, 113, 73,-32768,
+ 337,-32768, 70,-32768, 75, 74, 121, 567, 505, 113,
+-32768,-32768, 118, 81, 84, 92, 114, 505, 109,-32768,
+ 89,-32768,-32768,-32768,-32768, 5,-32768,-32768, 567, 113,
+ 7, 213, 95, 505,-32768,-32768, 18,-32768,-32768,-32768,
+ 113, 505,-32768, 140,-32768
+};
+
+static const short yypgoto[] = {-32768,
+-32768, -124,-32768, -30, 1, -2,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 22,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, -17,-32768,-32768, -144,-32768, 0,-32768,-32768,
+-32768, 144
+};
+
+
+#define YYLAST 683
+
+
+static const short yytable[] = { 39,
+ 63, 33, 40, 156, 47, 41, 41, 65, 48, 175,
+ 42, 108, 112, 149, 50, 72, 41, 73, 94, 61,
+ 94, 141, 46, 52, 173, 158, 53, 56, 57, 54,
+ 146, 79, 66, 67, 68, 69, 70, 71, 42, 88,
+ 77, 78, 113, 63, 64, 174, 80, 82, 176, 84,
+ 65, 86, 87, 136, 92, 39, 182, 95, 62, 95,
+ 147, 96, 97, 180, 100, 101, 102, 103, 104, 105,
+ 106, 68, 69, 70, 71, 66, 67, 68, 69, 70,
+ 71, 83, 119, 85, 121, 109, 71, 117, 111, 110,
+ 134, 124, 126, 3, 125, 5, 6, 127, 128, 7,
+ 133, 135, 136, 11, 137, 142, 129, 78, 16, 132,
+ 17, 18, 19, 143, 20, 144, 150, 23, 152, 153,
+ 159, 154, 27, 92, 28, 63, 64, 43, 155, 160,
+ 29, 161, 65, 162, 166, 163, 130, 168, 178, 185,
+ 78, 177, 44, 18, 19, 140, 157, 119, 171, 23,
+ 45, 0, 0, 0, 27, 165, 0, 66, 67, 68,
+ 69, 70, 71, 0, 0, 93, 0, 0, 119, 184,
+ 2, 179, -8, 0, 0, 3, 4, 5, 6, 183,
+ 0, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 0, 17, 18, 19, 0, 20, 21, 22, 23,
+ 24, 25, 26, 0, 27, 0, 28, 0, 0, 0,
+ 0, -8, 29, 58, 30, -12, 0, 0, 3, 4,
+ 5, 6, 0, 0, 7, 0, 9, 10, 11, 12,
+ 13, 14, 15, 16, 0, 17, 18, 19, 0, 20,
+ 21, 22, 23, 24, 25, 26, 0, 27, 0, 28,
+ 0, 0, 0, 0, -12, 29, 0, 30, -12, 58,
+ 0, -14, 0, 0, 3, 4, 5, 6, 0, 0,
+ 7, 0, 9, 10, 11, 12, 13, 14, 15, 16,
+ 0, 17, 18, 19, 0, 20, 21, 22, 23, 24,
+ 25, 26, 0, 27, 0, 28, 0, 0, 0, 0,
+ -14, 29, 0, 30, -14, 58, 0, -11, 0, 0,
+ 3, 4, 5, 6, 0, 0, 7, 0, 9, 10,
+ 11, 12, 13, 14, 15, 16, 0, 17, 18, 19,
+ 0, 20, 21, 22, 23, 24, 25, 26, 0, 27,
+ 0, 28, 3, 0, 5, 6, -11, 29, 7, 30,
+ 0, 0, 11, 0, 0, 0, 0, 16, 0, 17,
+ 18, 19, 0, 20, 0, 0, 23, 0, 0, 0,
+ 0, 27, 0, 28, 0, 0, 0, 38, 0, 29,
+ 3, 4, 5, 6, 0, 151, 7, 0, 9, 10,
+ 11, 12, 13, 14, 15, 16, 0, 17, 18, 19,
+ 0, 20, 21, 22, 23, 24, 25, 26, 0, 27,
+ 0, 28, 0, 63, 64, 0, 0, 29, 0, 30,
+ 65, 0, 63, 64, 0, 0, 0, 0, 0, 65,
+ 0, 63, 64, 0, 0, 0, 0, 0, 65, 66,
+ 67, 68, 69, 70, 71, 66, 67, 68, 69, 70,
+ 71, 0, 65, 116, 66, 67, 68, 69, 70, 71,
+ 0, 0, 120, 66, 67, 68, 69, 70, 71, 63,
+ 64, 122, 0, 0, 0, 0, 65, 66, 67, 68,
+ 69, 70, 71, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 66, 67, 68, 69, 70, 71, 0, 0, 123,
+ 3, 4, 5, 6, 0, 0, 7, 0, 9, 10,
+ 11, 12, 13, 14, 15, 16, 0, 17, 18, 19,
+ 0, 20, 21, 22, 23, 24, 25, 26, 0, 27,
+ 0, 28, 3, 89, 5, 6, 0, 29, 7, 30,
+ 0, 0, 11, 0, 0, 0, 0, 16, 0, 17,
+ 18, 19, 0, 20, 0, 0, 23, 0, 0, 0,
+ 0, 27, 3, 28, 5, 6, 0, 0, 7, 29,
+ 0, 0, 11, 0, 0, 0, 0, 16, 0, 17,
+ 18, 19, 0, 20, 0, 0, 23, 0, 0, 0,
+ 0, 27, 3, 28, 74, 6, 0, 0, 7, 29,
+ 0, 0, 11, 0, 0, 0, 0, 16, 0, 17,
+ 18, 19, 0, 20, 0, 0, 23, 0, 0, 0,
+ 0, 27, 3, 28, 131, 6, 0, 0, 7, 29,
+ 0, 0, 11, 0, 0, 63, 64, 16, 0, 17,
+ 18, 19, 65, 20, 0, 0, 23, 0, 0, 0,
+ 0, 27, 0, 28, 0, 0, 0, 0, 0, 29,
+ 0, 0, 0, 0, 0, 0, 0, 66, 67, 68,
+ 69, 70, 71
+};
+
+static const short yycheck[] = { 2,
+ 4, 1, 3, 148, 43, 43, 43, 11, 43, 3,
+ 48, 48, 8, 138, 43, 10, 43, 12, 3, 3,
+ 3, 48, 8, 43, 169, 150, 43, 28, 29, 43,
+ 8, 43, 36, 37, 38, 39, 40, 41, 48, 44,
+ 41, 42, 38, 4, 5, 170, 47, 48, 42, 50,
+ 11, 52, 53, 47, 55, 58, 181, 42, 42, 42,
+ 38, 46, 62, 46, 65, 66, 67, 68, 69, 70,
+ 71, 38, 39, 40, 41, 36, 37, 38, 39, 40,
+ 41, 43, 83, 43, 85, 44, 41, 44, 49, 47,
+ 8, 47, 95, 6, 94, 8, 9, 98, 99, 12,
+ 48, 44, 47, 16, 42, 49, 107, 108, 21, 110,
+ 23, 24, 25, 48, 27, 3, 44, 30, 49, 45,
+ 3, 48, 35, 124, 37, 4, 5, 8, 8, 49,
+ 43, 48, 11, 42, 26, 22, 49, 49, 44, 0,
+ 141, 172, 23, 24, 25, 124, 149, 148, 166, 30,
+ 7, -1, -1, -1, 35, 158, -1, 36, 37, 38,
+ 39, 40, 41, -1, -1, 44, -1, -1, 169, 0,
+ 1, 174, 3, -1, -1, 6, 7, 8, 9, 182,
+ -1, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, -1, 23, 24, 25, -1, 27, 28, 29, 30,
+ 31, 32, 33, -1, 35, -1, 37, -1, -1, -1,
+ -1, 42, 43, 1, 45, 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, -1, 35, -1, 37,
+ -1, -1, -1, -1, 42, 43, -1, 45, 46, 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, -1, 35, -1, 37, -1, -1, -1, -1,
+ 42, 43, -1, 45, 46, 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, -1, 35,
+ -1, 37, 6, -1, 8, 9, 42, 43, 12, 45,
+ -1, -1, 16, -1, -1, -1, -1, 21, -1, 23,
+ 24, 25, -1, 27, -1, -1, 30, -1, -1, -1,
+ -1, 35, -1, 37, -1, -1, -1, 3, -1, 43,
+ 6, 7, 8, 9, -1, 49, 12, -1, 14, 15,
+ 16, 17, 18, 19, 20, 21, -1, 23, 24, 25,
+ -1, 27, 28, 29, 30, 31, 32, 33, -1, 35,
+ -1, 37, -1, 4, 5, -1, -1, 43, -1, 45,
+ 11, -1, 4, 5, -1, -1, -1, -1, -1, 11,
+ -1, 4, 5, -1, -1, -1, -1, -1, 11, 36,
+ 37, 38, 39, 40, 41, 36, 37, 38, 39, 40,
+ 41, -1, 11, 44, 36, 37, 38, 39, 40, 41,
+ -1, -1, 44, 36, 37, 38, 39, 40, 41, 4,
+ 5, 44, -1, -1, -1, -1, 11, 36, 37, 38,
+ 39, 40, 41, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 36, 37, 38, 39, 40, 41, -1, -1, 44,
+ 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, -1, 35,
+ -1, 37, 6, 7, 8, 9, -1, 43, 12, 45,
+ -1, -1, 16, -1, -1, -1, -1, 21, -1, 23,
+ 24, 25, -1, 27, -1, -1, 30, -1, -1, -1,
+ -1, 35, 6, 37, 8, 9, -1, -1, 12, 43,
+ -1, -1, 16, -1, -1, -1, -1, 21, -1, 23,
+ 24, 25, -1, 27, -1, -1, 30, -1, -1, -1,
+ -1, 35, 6, 37, 8, 9, -1, -1, 12, 43,
+ -1, -1, 16, -1, -1, -1, -1, 21, -1, 23,
+ 24, 25, -1, 27, -1, -1, 30, -1, -1, -1,
+ -1, 35, 6, 37, 8, 9, -1, -1, 12, 43,
+ -1, -1, 16, -1, -1, 4, 5, 21, -1, 23,
+ 24, 25, 11, 27, -1, -1, 30, -1, -1, -1,
+ -1, 35, -1, 37, -1, -1, -1, -1, -1, 43,
+ -1, -1, -1, -1, -1, -1, -1, 36, 37, 38,
+ 39, 40, 41
+};
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/usr/gnu/share/bison.simple"
+
+/* Skeleton output parser for bison,
+ Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* 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. */
+
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not GNU C. */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
+#include <alloca.h>
+#else /* not sparc */
+#if defined (MSDOS) && !defined (__TURBOC__)
+#include <malloc.h>
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+#include <malloc.h>
+ #pragma alloca
+#else /* not MSDOS, __TURBOC__, or _AIX */
+#ifdef __hpux
+#ifdef __cplusplus
+extern "C" {
+void *alloca (unsigned int);
+};
+#else /* not __cplusplus */
+void *alloca ();
+#endif /* not __cplusplus */
+#endif /* __hpux */
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc. */
+#endif /* not GNU C. */
+#endif /* alloca not defined. */
+
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* Note: there must be only one dollar sign in this file.
+ It is replaced by the list of actions, each action
+ as one case of the switch. */
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+#define YYERROR goto yyerrlab1
+/* 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); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { yyerror ("syntax error: cannot back up"); YYERROR; } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+#ifndef YYPURE
+#define YYLEX yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int yychar; /* the lookahead symbol */
+YYSTYPE yylval; /* the semantic value of the */
+ /* lookahead symbol */
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc; /* location data for the lookahead */
+ /* symbol */
+#endif
+
+int yynerrs; /* number of parse errors so far */
+#endif /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug; /* nonzero means print parse trace */
+/* Since this is uninitialized, it does not stop multiple parsers
+ from coexisting. */
+#endif
+
+/* YYINITDEPTH indicates the initial size of the parser's stacks */
+
+#ifndef YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH is the maximum size the stacks can grow to
+ (effective only if the built-in stack extension method is used). */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+int yyparse (void);
+#endif
+
+#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
+#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
+#else /* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (to, from, count)
+ char *to;
+ char *from;
+ int count;
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+ in available built-in functions on various systems. */
+static void
+__yy_memcpy (char *to, char *from, int count)
+{
+ register char *f = from;
+ register char *t = to;
+ register int i = count;
+
+ while (i-- > 0)
+ *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 196 "/usr/gnu/share/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+ register int yystate;
+ register int yyn;
+ register short *yyssp;
+ register YYSTYPE *yyvsp;
+ int yyerrstatus; /* number of tokens to shift before error messages enabled */
+ int yychar1 = 0; /* lookahead token as an internal (translated) token number */
+
+ short yyssa[YYINITDEPTH]; /* the state stack */
+ YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
+
+ short *yyss = yyssa; /* refer to the stacks thru separate pointers */
+ YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+
+#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ int yystacksize = YYINITDEPTH;
+
+#ifdef YYPURE
+ int yychar;
+ YYSTYPE yylval;
+ int yynerrs;
+#ifdef YYLSP_NEEDED
+ YYLTYPE yylloc;
+#endif
+#endif
+
+ YYSTYPE yyval; /* the variable used to return */
+ /* semantic values from the action */
+ /* routines */
+
+ int yylen;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Starting parse\n");
+#endif
+
+ 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 - 1;
+ yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in yystate . */
+/* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks. */
+yynewstate:
+
+ *++yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* 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 *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+#endif
+
+ /* Get the current used size of the three stacks, in elements. */
+ int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ /* Each stack pointer address is followed by the size of
+ the data in use in that stack, in bytes. */
+#ifdef YYLSP_NEEDED
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yyls1, size * sizeof (*yylsp),
+ &yystacksize);
+#else
+ yyoverflow("parser stack overflow",
+ &yyss1, size * sizeof (*yyssp),
+ &yyvs1, size * sizeof (*yyvsp),
+ &yystacksize);
+#endif
+
+ yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+ yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ {
+ yyerror("parser stack overflow");
+ return 2;
+ }
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+ yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
+ yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+ yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + size - 1;
+ yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+ yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+ goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Reading a token: ");
+#endif
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Now at end of input.\n");
+#endif
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise meaning
+ of a token, for further debugging info. */
+#ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+#endif
+ fprintf (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrlab;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ /* count tokens shifted since error; after three, turn off error status. */
+ if (yyerrstatus) yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+/* Do the default action for the current state. */
+yydefault:
+
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+
+/* Do a reduction. yyn is the number of a rule to reduce with. */
+yyreduce:
+ yylen = yyr2[yyn];
+ if (yylen > 0)
+ yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ int i;
+
+ fprintf (stderr, "Reducing via rule %d (line %d), ",
+ yyn, yyrline[yyn]);
+
+ /* Print the symbols being reduced, and their result. */
+ for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+ fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+ fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+ }
+#endif
+
+
+ switch (yyn) {
+
+case 1:
+#line 106 "bc.y"
+{
+ yyval.i_value = 0;
+ if (interactive && !quiet)
+ {
+ printf ("%s\n", BC_VERSION);
+ welcome ();
+ }
+ ;
+ break;}
+case 3:
+#line 117 "bc.y"
+{ run_code (); ;
+ break;}
+case 4:
+#line 119 "bc.y"
+{ run_code (); ;
+ break;}
+case 5:
+#line 121 "bc.y"
+{
+ yyerrok;
+ init_gen ();
+ ;
+ break;}
+case 7:
+#line 128 "bc.y"
+{ warn ("newline not allowed"); ;
+ break;}
+case 8:
+#line 131 "bc.y"
+{ yyval.i_value = 0; ;
+ break;}
+case 12:
+#line 137 "bc.y"
+{ yyval.i_value = 0; ;
+ break;}
+case 19:
+#line 146 "bc.y"
+{ yyval.i_value = yyvsp[0].i_value; ;
+ break;}
+case 20:
+#line 149 "bc.y"
+{ warranty (""); ;
+ break;}
+case 21:
+#line 151 "bc.y"
+{ limits (); ;
+ break;}
+case 22:
+#line 153 "bc.y"
+{
+ if (yyvsp[0].i_value & 2)
+ warn ("comparison in expression");
+ if (yyvsp[0].i_value & 1)
+ generate ("W");
+ else
+ generate ("p");
+ ;
+ break;}
+case 23:
+#line 162 "bc.y"
+{
+ yyval.i_value = 0;
+ generate ("w");
+ generate (yyvsp[0].s_value);
+ free (yyvsp[0].s_value);
+ ;
+ break;}
+case 24:
+#line 169 "bc.y"
+{
+ if (break_label == 0)
+ yyerror ("Break outside a for/while");
+ else
+ {
+ sprintf (genstr, "J%1d:", break_label);
+ generate (genstr);
+ }
+ ;
+ break;}
+case 25:
+#line 179 "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 26:
+#line 190 "bc.y"
+{ exit (0); ;
+ break;}
+case 27:
+#line 192 "bc.y"
+{ generate ("h"); ;
+ break;}
+case 28:
+#line 194 "bc.y"
+{ generate ("0R"); ;
+ break;}
+case 29:
+#line 196 "bc.y"
+{ generate ("R"); ;
+ break;}
+case 30:
+#line 198 "bc.y"
+{
+ yyvsp[0].i_value = break_label;
+ break_label = next_label++;
+ ;
+ break;}
+case 31:
+#line 203 "bc.y"
+{
+ if (yyvsp[-1].i_value > 1)
+ warn ("Comparison in first for expression");
+ yyvsp[-1].i_value = next_label++;
+ if (yyvsp[-1].i_value < 0)
+ sprintf (genstr, "N%1d:", yyvsp[-1].i_value);
+ else
+ sprintf (genstr, "pN%1d:", yyvsp[-1].i_value);
+ generate (genstr);
+ ;
+ break;}
+case 32:
+#line 214 "bc.y"
+{
+ if (yyvsp[-1].i_value < 0) 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 225 "bc.y"
+{
+ if (yyvsp[-1].i_value > 1)
+ warn ("Comparison in third for expression");
+ if (yyvsp[-1].i_value < 0)
+ 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 235 "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 243 "bc.y"
+{
+ yyvsp[-1].i_value = if_label;
+ if_label = next_label++;
+ sprintf (genstr, "Z%1d:", if_label);
+ generate (genstr);
+ ;
+ break;}
+case 36:
+#line 250 "bc.y"
+{
+ sprintf (genstr, "N%1d:", if_label);
+ generate (genstr);
+ if_label = yyvsp[-5].i_value;
+ ;
+ break;}
+case 37:
+#line 256 "bc.y"
+{
+ yyvsp[0].i_value = next_label++;
+ sprintf (genstr, "N%1d:", yyvsp[0].i_value);
+ generate (genstr);
+ ;
+ break;}
+case 38:
+#line 262 "bc.y"
+{
+ yyvsp[0].i_value = break_label;
+ break_label = next_label++;
+ sprintf (genstr, "Z%1d:", break_label);
+ generate (genstr);
+ ;
+ break;}
+case 39:
+#line 269 "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 275 "bc.y"
+{ yyval.i_value = 0; ;
+ break;}
+case 41:
+#line 277 "bc.y"
+{ warn ("print statement"); ;
+ break;}
+case 45:
+#line 284 "bc.y"
+{
+ generate ("O");
+ generate (yyvsp[0].s_value);
+ free (yyvsp[0].s_value);
+ ;
+ break;}
+case 46:
+#line 290 "bc.y"
+{ generate ("P"); ;
+ break;}
+case 48:
+#line 294 "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 304 "bc.y"
+{
+ /* Check auto list against parameter list? */
+ check_params (yyvsp[-5].a_value,yyvsp[0].a_value);
+ sprintf (genstr, "F%d,%s.%s[",
+ lookup(yyvsp[-7].s_value,FUNCTDEF),
+ arg_str (yyvsp[-5].a_value), arg_str (yyvsp[0].a_value));
+ generate (genstr);
+ free_args (yyvsp[-5].a_value);
+ free_args (yyvsp[0].a_value);
+ yyvsp[-8].i_value = next_label;
+ next_label = 1;
+ ;
+ break;}
+case 51:
+#line 317 "bc.y"
+{
+ generate ("0R]");
+ next_label = yyvsp[-11].i_value;
+ ;
+ break;}
+case 52:
+#line 323 "bc.y"
+{ yyval.a_value = NULL; ;
+ break;}
+case 54:
+#line 327 "bc.y"
+{ yyval.a_value = NULL; ;
+ break;}
+case 55:
+#line 329 "bc.y"
+{ yyval.a_value = yyvsp[-1].a_value; ;
+ break;}
+case 56:
+#line 331 "bc.y"
+{ yyval.a_value = yyvsp[-1].a_value; ;
+ break;}
+case 57:
+#line 334 "bc.y"
+{ yyval.a_value = nextarg (NULL, lookup (yyvsp[0].s_value,SIMPLE), FALSE);;
+ break;}
+case 58:
+#line 336 "bc.y"
+{ yyval.a_value = nextarg (NULL, lookup (yyvsp[-2].s_value,ARRAY), FALSE); ;
+ break;}
+case 59:
+#line 338 "bc.y"
+{ yyval.a_value = nextarg (NULL, lookup (yyvsp[-2].s_value,ARRAY), TRUE); ;
+ break;}
+case 60:
+#line 340 "bc.y"
+{ yyval.a_value = nextarg (yyvsp[-2].a_value, lookup (yyvsp[0].s_value,SIMPLE), FALSE); ;
+ break;}
+case 61:
+#line 342 "bc.y"
+{ yyval.a_value = nextarg (yyvsp[-4].a_value, lookup (yyvsp[-2].s_value,ARRAY), FALSE); ;
+ break;}
+case 62:
+#line 344 "bc.y"
+{ yyval.a_value = nextarg (yyvsp[-5].a_value, lookup (yyvsp[-2].s_value,ARRAY), TRUE); ;
+ break;}
+case 63:
+#line 347 "bc.y"
+{ yyval.a_value = NULL; ;
+ break;}
+case 65:
+#line 351 "bc.y"
+{
+ if (yyvsp[0].i_value > 1) warn ("comparison in argument");
+ yyval.a_value = nextarg (NULL,0,FALSE);
+ ;
+ break;}
+case 66:
+#line 356 "bc.y"
+{
+ sprintf (genstr, "K%d:", -lookup (yyvsp[-2].s_value,ARRAY));
+ generate (genstr);
+ yyval.a_value = nextarg (NULL,1,FALSE);
+ ;
+ break;}
+case 67:
+#line 362 "bc.y"
+{
+ if (yyvsp[0].i_value > 1) warn ("comparison in argument");
+ yyval.a_value = nextarg (yyvsp[-2].a_value,0,FALSE);
+ ;
+ break;}
+case 68:
+#line 367 "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 69:
+#line 374 "bc.y"
+{
+ yyval.i_value = -1;
+ warn ("Missing expression in for statement");
+ ;
+ break;}
+case 71:
+#line 381 "bc.y"
+{
+ yyval.i_value = 0;
+ generate ("0");
+ ;
+ break;}
+case 72:
+#line 386 "bc.y"
+{
+ if (yyvsp[0].i_value > 1)
+ warn ("comparison in return expresion");
+ ;
+ break;}
+case 73:
+#line 392 "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 74:
+#line 403 "bc.y"
+{
+ if (yyvsp[0].i_value > 1) warn("comparison in assignment");
+ 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 = 0;
+ ;
+ break;}
+case 75:
+#line 419 "bc.y"
+{
+ warn("&& operator");
+ yyvsp[0].i_value = next_label++;
+ sprintf (genstr, "DZ%d:p", yyvsp[0].i_value);
+ generate (genstr);
+ ;
+ break;}
+case 76:
+#line 426 "bc.y"
+{
+ 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;
+ ;
+ break;}
+case 77:
+#line 432 "bc.y"
+{
+ warn("|| operator");
+ yyvsp[0].i_value = next_label++;
+ sprintf (genstr, "B%d:", yyvsp[0].i_value);
+ generate (genstr);
+ ;
+ break;}
+case 78:
+#line 439 "bc.y"
+{
+ int tmplab;
+ 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;
+ ;
+ break;}
+case 79:
+#line 448 "bc.y"
+{
+ yyval.i_value = yyvsp[0].i_value;
+ warn("! operator");
+ generate ("!");
+ ;
+ break;}
+case 80:
+#line 454 "bc.y"
+{
+ yyval.i_value = 3;
+ 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 81:
+#line 482 "bc.y"
+{
+ generate ("+");
+ yyval.i_value = yyvsp[-2].i_value | yyvsp[0].i_value;
+ ;
+ break;}
+case 82:
+#line 487 "bc.y"
+{
+ generate ("-");
+ yyval.i_value = yyvsp[-2].i_value | yyvsp[0].i_value;
+ ;
+ break;}
+case 83:
+#line 492 "bc.y"
+{
+ generate ("*");
+ yyval.i_value = yyvsp[-2].i_value | yyvsp[0].i_value;
+ ;
+ break;}
+case 84:
+#line 497 "bc.y"
+{
+ generate ("/");
+ yyval.i_value = yyvsp[-2].i_value | yyvsp[0].i_value;
+ ;
+ break;}
+case 85:
+#line 502 "bc.y"
+{
+ generate ("%");
+ yyval.i_value = yyvsp[-2].i_value | yyvsp[0].i_value;
+ ;
+ break;}
+case 86:
+#line 507 "bc.y"
+{
+ generate ("^");
+ yyval.i_value = yyvsp[-2].i_value | yyvsp[0].i_value;
+ ;
+ break;}
+case 87:
+#line 512 "bc.y"
+{
+ generate ("n");
+ yyval.i_value = yyvsp[0].i_value;
+ ;
+ break;}
+case 88:
+#line 517 "bc.y"
+{
+ yyval.i_value = 1;
+ 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 89:
+#line 526 "bc.y"
+{
+ int len = strlen(yyvsp[0].s_value);
+ yyval.i_value = 1;
+ 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 90:
+#line 542 "bc.y"
+{ yyval.i_value = yyvsp[-1].i_value | 1; ;
+ break;}
+case 91:
+#line 544 "bc.y"
+{
+ yyval.i_value = 1;
+ if (yyvsp[-1].a_value != NULL)
+ {
+ sprintf (genstr, "C%d,%s:",
+ lookup (yyvsp[-3].s_value,FUNCT),
+ call_str (yyvsp[-1].a_value));
+ free_args (yyvsp[-1].a_value);
+ }
+ else
+ {
+ sprintf (genstr, "C%d:", lookup (yyvsp[-3].s_value,FUNCT));
+ }
+ generate (genstr);
+ ;
+ break;}
+case 92:
+#line 560 "bc.y"
+{
+ yyval.i_value = 1;
+ 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 93:
+#line 579 "bc.y"
+{
+ yyval.i_value = 1;
+ 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 94:
+#line 602 "bc.y"
+{ generate ("cL"); yyval.i_value = 1;;
+ break;}
+case 95:
+#line 604 "bc.y"
+{ generate ("cR"); yyval.i_value = 1;;
+ break;}
+case 96:
+#line 606 "bc.y"
+{ generate ("cS"); yyval.i_value = 1;;
+ break;}
+case 97:
+#line 608 "bc.y"
+{
+ warn ("read function");
+ generate ("cI"); yyval.i_value = 1;
+ ;
+ break;}
+case 98:
+#line 614 "bc.y"
+{ yyval.i_value = lookup(yyvsp[0].s_value,SIMPLE); ;
+ break;}
+case 99:
+#line 616 "bc.y"
+{
+ if (yyvsp[-1].i_value > 1) warn("comparison in subscript");
+ yyval.i_value = lookup(yyvsp[-3].s_value,ARRAY);
+ ;
+ break;}
+case 100:
+#line 621 "bc.y"
+{ yyval.i_value = 0; ;
+ break;}
+case 101:
+#line 623 "bc.y"
+{ yyval.i_value = 1; ;
+ break;}
+case 102:
+#line 625 "bc.y"
+{ yyval.i_value = 2; ;
+ break;}
+case 103:
+#line 627 "bc.y"
+{ yyval.i_value = 3;
+ warn ("History variable");
+ ;
+ break;}
+case 104:
+#line 631 "bc.y"
+{ yyval.i_value = 4;
+ warn ("Last variable");
+ ;
+ break;}
+}
+ /* the action file gets copied in in place of this dollarsign */
+#line 498 "/usr/gnu/share/bison.simple"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+ yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+ *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+ yylsp++;
+ if (yylen == 0)
+ {
+ yylsp->first_line = yylloc.first_line;
+ yylsp->first_column = yylloc.first_column;
+ yylsp->last_line = (yylsp-1)->last_line;
+ yylsp->last_column = (yylsp-1)->last_column;
+ yylsp->text = 0;
+ }
+ else
+ {
+ yylsp->last_line = (yylsp+yylen-1)->last_line;
+ yylsp->last_column = (yylsp+yylen-1)->last_column;
+ }
+#endif
+
+ /* 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 - YYNTBASE] + *yyssp;
+ if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTBASE];
+
+ goto yynewstate;
+
+yyerrlab: /* here on detecting error */
+
+ if (! yyerrstatus)
+ /* If not already recovering from an error, report this error. */
+ {
+ ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (yyn > YYFLAG && yyn < YYLAST)
+ {
+ int size = 0;
+ char *msg;
+ int x, count;
+
+ count = 0;
+ /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ size += strlen(yytname[x]) + 15, count++;
+ msg = (char *) malloc(size + 15);
+ if (msg != 0)
+ {
+ strcpy(msg, "parse error");
+
+ if (count < 5)
+ {
+ count = 0;
+ for (x = (yyn < 0 ? -yyn : 0);
+ x < (sizeof(yytname) / sizeof(char *)); x++)
+ if (yycheck[x + yyn] == x)
+ {
+ strcat(msg, count == 0 ? ", expecting `" : " or `");
+ strcat(msg, yytname[x]);
+ strcat(msg, "'");
+ count++;
+ }
+ }
+ yyerror(msg);
+ free(msg);
+ }
+ else
+ yyerror ("parse error; also virtual memory exceeded");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror("parse error");
+ }
+
+ goto yyerrlab1;
+yyerrlab1: /* here on error raised explicitly by an action */
+
+ if (yyerrstatus == 3)
+ {
+ /* if just tried and failed to reuse lookahead token after an error, discard it. */
+
+ /* return failure if at end of input */
+ if (yychar == YYEOF)
+ YYABORT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+ yychar = YYEMPTY;
+ }
+
+ /* Else will try to reuse lookahead token
+ after shifting the error token. */
+
+ yyerrstatus = 3; /* Each real token shifted decrements this */
+
+ goto yyerrhandle;
+
+yyerrdefault: /* current state does not do anything special for the error token. */
+
+#if 0
+ /* This is wrong; only states that explicitly want error tokens
+ should shift them. */
+ yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
+ if (yyn) goto yydefault;
+#endif
+
+yyerrpop: /* pop the current state because it cannot handle the error token */
+
+ if (yyssp == yyss) YYABORT;
+ yyvsp--;
+ yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+ yylsp--;
+#endif
+
+#if YYDEBUG != 0
+ if (yydebug)
+ {
+ short *ssp1 = yyss - 1;
+ fprintf (stderr, "Error: state stack now");
+ while (ssp1 != yyssp)
+ fprintf (stderr, " %d", *++ssp1);
+ fprintf (stderr, "\n");
+ }
+#endif
+
+yyerrhandle:
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yyerrdefault;
+
+ yyn += YYTERROR;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+ goto yyerrdefault;
+
+ yyn = yytable[yyn];
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrpop;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+ else if (yyn == 0)
+ goto yyerrpop;
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+#if YYDEBUG != 0
+ if (yydebug)
+ fprintf(stderr, "Shifting error token, ");
+#endif
+
+ *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+ *++yylsp = yylloc;
+#endif
+
+ yystate = yyn;
+ goto yynewstate;
+}
+#line 636 "bc.y"
+
+
diff --git a/contrib/bc/bc/bc.h b/contrib/bc/bc/bc.h
new file mode 100644
index 000000000000..e5a100941a03
--- /dev/null
+++ b/contrib/bc/bc/bc.h
@@ -0,0 +1,42 @@
+typedef union {
+ char *s_value;
+ char c_value;
+ int i_value;
+ arg_list *a_value;
+ } YYSTYPE;
+#define NEWLINE 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 Warranty 283
+#define Halt 284
+#define Last 285
+#define Continue 286
+#define Print 287
+#define Limits 288
+#define UNARY_MINUS 289
+#define History 290
+
+
+extern YYSTYPE yylval;
diff --git a/contrib/bc/bc/bc.y b/contrib/bc/bc/bc.y
new file mode 100644
index 000000000000..81e77a88e588
--- /dev/null
+++ b/contrib/bc/bc/bc.y
@@ -0,0 +1,637 @@
+%{
+/* bc.y: The grammar for a POSIX compatable bc processor with some
+ extensions to the language. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+#include "bcdefs.h"
+#include "global.h"
+#include "proto.h"
+%}
+
+%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 grammer 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> NEWLINE 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' */
+%token <i_value> Scale Ibase Obase Auto Read
+/* 'warranty', 'halt', 'last', 'continue', 'print', 'limits' */
+%token <i_value> Warranty, Halt, Last, Continue, Print, Limits
+/* 'history' */
+%token <i_value> UNARY_MINUS History
+
+/* 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
+
+/* 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)
+ {
+ printf ("%s\n", BC_VERSION);
+ welcome ();
+ }
+ }
+ | program input_item
+ ;
+input_item : semicolon_list NEWLINE
+ { run_code (); }
+ | function
+ { run_code (); }
+ | error NEWLINE
+ {
+ yyerrok;
+ init_gen ();
+ }
+ ;
+opt_newline : /* empty */
+ | NEWLINE
+ { 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 NEWLINE
+ | statement_list NEWLINE statement_or_error
+ | statement_list ';'
+ | statement_list ';' statement
+ ;
+statement_or_error : statement
+ | error statement
+ { $$ = $2; }
+ ;
+statement : Warranty
+ { warranty (""); }
+ | Limits
+ { limits (); }
+ | expression
+ {
+ if ($1 & 2)
+ warn ("comparison in 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);
+ }
+ }
+ | 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
+ { generate ("0R"); }
+ | Return '(' return_expression ')'
+ { generate ("R"); }
+ | For
+ {
+ $1 = break_label;
+ break_label = next_label++;
+ }
+ '(' opt_expression ';'
+ {
+ if ($4 > 1)
+ warn ("Comparison in first for expression");
+ $4 = next_label++;
+ if ($4 < 0)
+ sprintf (genstr, "N%1d:", $4);
+ else
+ sprintf (genstr, "pN%1d:", $4);
+ generate (genstr);
+ }
+ opt_expression ';'
+ {
+ if ($7 < 0) 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 > 1)
+ warn ("Comparison in third for expression");
+ if ($10 < 0)
+ 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 ')'
+ {
+ $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
+ {
+ $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
+ { 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 NAME '(' opt_parameter_list ')' opt_newline
+ '{' NEWLINE opt_auto_define_list
+ {
+ /* Check auto list against parameter list? */
+ check_params ($4,$9);
+ sprintf (genstr, "F%d,%s.%s[",
+ lookup($2,FUNCTDEF),
+ arg_str ($4), arg_str ($9));
+ generate (genstr);
+ free_args ($4);
+ free_args ($9);
+ $1 = next_label;
+ next_label = 1;
+ }
+ statement_list /* NEWLINE */ '}'
+ {
+ generate ("0R]");
+ next_label = $1;
+ }
+ ;
+opt_parameter_list : /* empty */
+ { $$ = NULL; }
+ | define_list
+ ;
+opt_auto_define_list : /* empty */
+ { $$ = NULL; }
+ | Auto define_list NEWLINE
+ { $$ = $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); }
+ | 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); }
+ ;
+opt_argument_list : /* empty */
+ { $$ = NULL; }
+ | argument_list
+ ;
+argument_list : expression
+ {
+ if ($1 > 1) warn ("comparison in argument");
+ $$ = nextarg (NULL,0,FALSE);
+ }
+ | NAME '[' ']'
+ {
+ sprintf (genstr, "K%d:", -lookup ($1,ARRAY));
+ generate (genstr);
+ $$ = nextarg (NULL,1,FALSE);
+ }
+ | argument_list ',' expression
+ {
+ if ($3 > 1) warn ("comparison in argument");
+ $$ = nextarg ($1,0,FALSE);
+ }
+ | argument_list ',' NAME '[' ']'
+ {
+ sprintf (genstr, "K%d:", -lookup ($3,ARRAY));
+ generate (genstr);
+ $$ = nextarg ($1,1,FALSE);
+ }
+ ;
+opt_expression : /* empty */
+ {
+ $$ = -1;
+ warn ("Missing expression in for statement");
+ }
+ | expression
+ ;
+return_expression : /* empty */
+ {
+ $$ = 0;
+ generate ("0");
+ }
+ | expression
+ {
+ if ($1 > 1)
+ warn ("comparison in return expresion");
+ }
+ ;
+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 > 1) warn("comparison in assignment");
+ if ($2 != '=')
+ {
+ sprintf (genstr, "%c", $2);
+ generate (genstr);
+ }
+ if ($1 < 0)
+ sprintf (genstr, "S%d:", -$1);
+ else
+ sprintf (genstr, "s%d:", $1);
+ generate (genstr);
+ $$ = 0;
+ }
+ ;
+ | expression AND
+ {
+ warn("&& operator");
+ $2 = next_label++;
+ sprintf (genstr, "DZ%d:p", $2);
+ generate (genstr);
+ }
+ expression
+ {
+ sprintf (genstr, "DZ%d:p1N%d:", $2, $2);
+ generate (genstr);
+ $$ = $1 | $4;
+ }
+ | expression OR
+ {
+ warn("|| operator");
+ $2 = next_label++;
+ sprintf (genstr, "B%d:", $2);
+ generate (genstr);
+ }
+ expression
+ {
+ int tmplab;
+ tmplab = next_label++;
+ sprintf (genstr, "B%d:0J%d:N%d:1N%d:",
+ $2, tmplab, $2, tmplab);
+ generate (genstr);
+ $$ = $1 | $4;
+ }
+ | NOT expression
+ {
+ $$ = $2;
+ warn("! operator");
+ generate ("!");
+ }
+ | expression REL_OP expression
+ {
+ $$ = 3;
+ 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
+ {
+ generate ("+");
+ $$ = $1 | $3;
+ }
+ | expression '-' expression
+ {
+ generate ("-");
+ $$ = $1 | $3;
+ }
+ | expression '*' expression
+ {
+ generate ("*");
+ $$ = $1 | $3;
+ }
+ | expression '/' expression
+ {
+ generate ("/");
+ $$ = $1 | $3;
+ }
+ | expression '%' expression
+ {
+ generate ("%");
+ $$ = $1 | $3;
+ }
+ | expression '^' expression
+ {
+ generate ("^");
+ $$ = $1 | $3;
+ }
+ | '-' expression %prec UNARY_MINUS
+ {
+ generate ("n");
+ $$ = $2;
+ }
+ | 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 ')'
+ { $$ = $2 | 1; }
+ | NAME '(' opt_argument_list ')'
+ {
+ $$ = 1;
+ if ($3 != NULL)
+ {
+ sprintf (genstr, "C%d,%s:",
+ lookup ($1,FUNCT),
+ call_str ($3));
+ 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;}
+ | Read '(' ')'
+ {
+ warn ("read function");
+ generate ("cI"); $$ = 1;
+ }
+ ;
+named_expression : NAME
+ { $$ = lookup($1,SIMPLE); }
+ | NAME '[' expression ']'
+ {
+ if ($3 > 1) warn("comparison in subscript");
+ $$ = lookup($1,ARRAY);
+ }
+ | Ibase
+ { $$ = 0; }
+ | Obase
+ { $$ = 1; }
+ | Scale
+ { $$ = 2; }
+ | History
+ { $$ = 3;
+ warn ("History variable");
+ }
+ | Last
+ { $$ = 4;
+ warn ("Last variable");
+ }
+ ;
+
+%%
+
diff --git a/contrib/bc/bc/execute.c b/contrib/bc/bc/execute.c
new file mode 100644
index 000000000000..c8f3df26135a
--- /dev/null
+++ b/contrib/bc/bc/execute.c
@@ -0,0 +1,786 @@
+/* execute.c - run a bc program. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+#include "bcdefs.h"
+#include <signal.h>
+#include "global.h"
+#include "proto.h"
+
+
+/* The SIGINT interrupt handling routine. */
+
+int had_sigint;
+
+void
+stop_execution (sig)
+ int sig;
+{
+ had_sigint = TRUE;
+ printf ("\n");
+ rt_error ("interrupted execution");
+}
+
+
+/* Get the current byte and advance the PC counter. */
+
+unsigned char
+byte (pc)
+ program_counter *pc;
+{
+ int seg, offset;
+
+ seg = pc->pc_addr >> BC_SEG_LOG;
+ offset = pc->pc_addr++ % BC_SEG_SIZE;
+ return (functions[pc->pc_func].f_body[seg][offset]);
+}
+
+
+/* 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;
+ 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)
+ {
+ 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);
+ out_num (temp->s_num, 10, out_char);
+ depth++;
+ temp = temp->s_next;
+ }
+ }
+ }
+#endif
+
+ switch ( inst )
+ {
+
+ case 'A' : /* increment array variable (Add one). */
+ var_name = byte(&pc);
+ if ((var_name & 0x80) != 0)
+ var_name = ((var_name << 8) & 0x7f) + 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 = !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 << 8) & 0x7f) + 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 << 8) & 0x7f) + 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 << 8) & 0x7f) + 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 << 8) & 0x7f) + byte(&pc);
+ store_array (var_name);
+ break;
+
+ case 'T' : /* Test tos for zero */
+ c_code = 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. */
+ out_num (ex_stack->s_num, o_base, out_char);
+ 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 )
+ int2num (&ex_stack->s_num, ex_stack->s_num->n_scale);
+ else
+ int2num (&ex_stack->s_num, ex_stack->s_num->n_len
+ + ex_stack->s_num->n_scale);
+ break;
+
+ case 'S': /* Scale function. */
+ 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;
+ }
+ break;
+
+ case 'd' : /* Decrement number */
+ var_name = byte(&pc);
+ if ((var_name & 0x80) != 0)
+ var_name = ((var_name << 8) & 0x7f) + 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 << 8) & 0x7f) + byte(&pc);
+ incr_var (var_name);
+ break;
+
+ case 'l' : /* load variable */
+ var_name = byte(&pc);
+ if ((var_name & 0x80) != 0)
+ var_name = ((var_name << 8) & 0x7f) + 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 << 8) & 0x7f) + 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 0. */
+ push_copy (_one_);
+ break;
+
+ case '!' : /* Negate the boolean value on top of the stack. */
+ c_code = is_zero (ex_stack->s_num);
+ assign (c_code);
+ break;
+
+ case '&' : /* compare greater than */
+ if (check_stack(2))
+ {
+ c_code = !is_zero (ex_stack->s_next->s_num)
+ && !is_zero (ex_stack->s_num);
+ pop ();
+ assign (c_code);
+ }
+ break;
+
+ case '|' : /* compare greater than */
+ if (check_stack(2))
+ {
+ c_code = !is_zero (ex_stack->s_next->s_num)
+ || !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);
+ 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);
+ 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);
+ 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);
+ init_num (&temp_num);
+ }
+ else
+ rt_error ("Divide by zero");
+ }
+ break;
+
+ case '%' : /* remainder */
+ if (check_stack(2))
+ {
+ if (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);
+ 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 (is_zero (ex_stack->s_next->s_num) && is_neg (ex_stack->s_num))
+ rt_error ("divide by zero");
+ pop();
+ pop();
+ push_num (temp_num);
+ 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 ("Interruption completed.\n");
+ }
+}
+
+
+/* Prog_char gets another byte from the program. It is used for
+ conversion of text constants in the code to numbers. */
+
+char
+prog_char ()
+{
+ return byte(&pc);
+}
+
+
+/* Read a character from the standard input. This function is used
+ by the "read" function. */
+
+char
+input_char ()
+{
+ char 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();
+ }
+
+ /* 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)
+ char (*in_char)(VOID);
+ int conv_base;
+{
+ int digits;
+ bc_num build, temp, result, mult, divisor;
+ char in_ch, first_ch;
+ char negative;
+
+ /* Initialize all bc numbers */
+ init_num (&temp);
+ init_num (&result);
+ init_num (&mult);
+ build = copy_num (_zero_);
+ negative = FALSE;
+
+ /* The conversion base. */
+ 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;
+ 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);
+ 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;
+ free_num (&result);
+ free_num (&temp);
+ divisor = copy_num (_one_);
+ result = copy_num (_zero_);
+ digits = 0;
+ while (in_ch < 16)
+ {
+ bc_multiply (result, mult, &result, 0);
+ 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);
+ free_num (&temp);
+ free_num (&result);
+ 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 (pc)
+ program_counter *pc;
+{
+ bc_num build;
+ program_counter look_pc;
+ int kdigits, kscale;
+ char inchar;
+ char *ptr;
+
+ /* Count the digits and get things ready. */
+ look_pc = *pc;
+ 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 pc. */
+ inchar = byte(pc);
+
+ /* Secial cases of 0, 1, and A-F single inputs. */
+ if (kdigits == 1 && kscale == 0)
+ {
+ if (inchar == 0)
+ {
+ push_copy (_zero_);
+ inchar = byte(pc);
+ return;
+ }
+ if (inchar == 1) {
+ push_copy (_one_);
+ inchar = byte(pc);
+ return;
+ }
+ if (inchar > 9)
+ {
+ init_num (&build);
+ int2num (&build, inchar);
+ push_num (build);
+ inchar = byte(pc);
+ return;
+ }
+ }
+
+ /* Build the new number. */
+ if (kdigits == 0)
+ {
+ build = new_num (1,kscale);
+ ptr = build->n_value;
+ *ptr++ = 0;
+ }
+ else
+ {
+ build = new_num (kdigits,kscale);
+ ptr = build->n_value;
+ }
+
+ while (inchar != ':')
+ {
+ if (inchar != '.')
+ if (inchar > 9)
+ *ptr++ = 9;
+ else
+ *ptr++ = inchar;
+ inchar = byte(pc);
+ }
+ push_num (build);
+}
+
+
+/* Put the correct value on the stack for C_CODE. Frees TOS num. */
+
+void
+assign (c_code)
+ char c_code;
+{
+ free_num (&ex_stack->s_num);
+ if (c_code)
+ ex_stack->s_num = copy_num (_one_);
+ else
+ ex_stack->s_num = copy_num (_zero_);
+}
diff --git a/contrib/bc/bc/fix-libmath_h b/contrib/bc/bc/fix-libmath_h
new file mode 100755
index 000000000000..5a002c4f3247
--- /dev/null
+++ b/contrib/bc/bc/fix-libmath_h
@@ -0,0 +1,8 @@
+ed libmath.h <<EOS-EOS
+1,1s/^/"/
+1,\$s/\$/\\\\/
+\$,\$d
+\$,\$s/\\\\\$/"/
+w
+q
+EOS-EOS
diff --git a/contrib/bc/bc/global.c b/contrib/bc/bc/global.c
new file mode 100644
index 000000000000..3165434fae98
--- /dev/null
+++ b/contrib/bc/bc/global.c
@@ -0,0 +1,42 @@
+/* global.c: This defines the global variables. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+#include "bcdefs.h"
+
+/* Since we want to define them here, we use the following define. */
+#undef EXTERN
+#define EXTERN
+
+/* Define all the global variables for bc. */
+#include "global.h"
+
+#ifndef BC_MATH_FILE
+CONST char libmath[] =
+#include "libmath.h"
+;
+#endif
diff --git a/contrib/bc/bc/libmath.b b/contrib/bc/bc/libmath.b
new file mode 100644
index 000000000000..7549a576492d
--- /dev/null
+++ b/contrib/bc/bc/libmath.b
@@ -0,0 +1,279 @@
+/* libmath.b for GNU bc. */
+
+/* This file is part of GNU bc.
+ Copyright (C) 1991, 1992, 1993, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+
+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, 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. */
+
+ /* 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 e, f, i, m, n, v, z
+
+ /* 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 e, i, m, n, s, v, z
+
+ /* 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 v;
+ scale += 1;
+ v = s(x+a(1)*2);
+ scale -= 1;
+ 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, 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. */
+
+ /* 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, d, e, f, i, m, s, v, z
+
+ /* 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
+
+ /* 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/contrib/bc/bc/libmath.h b/contrib/bc/bc/libmath.h
new file mode 100644
index 000000000000..9481bb9301e7
--- /dev/null
+++ b/contrib/bc/bc/libmath.h
@@ -0,0 +1,40 @@
+"@iK20:s2:p@r\
+@iF1,5.6,7,8,9,10,11,12,13,14[l5:0<Z1:1s11:pl5:ns5:pN1:l2:s14:\
+pK6:l14:+K.44:l5:*+s12:pl5:cS1+s2:pN2:l5:1>Z3:l9:1+s9:pl5:K2:\
+/s5:pl2:1+s2:pJ2:N3:l12:s2:p1l5:+s13:pl5:s6:p1s7:pK2:s10:pN5:\
+1B6:J4:N7:l10:i10:pJ5:N6:l6:l5:*s6:l7:l10:*s7:/s8:pl8:0=Z8:l9:\
+0>Z9:N10:l9:d9:Z11:l13:l13:*s13:pJ10:N11:N9:l14:s2:pl11:Z12:1\
+l13:/RN12:l13:1/RN8:l13:l8:+s13:pJ7:N4:0R]@r\
+@iF2,5.8,9,10,11,12,13,14[l5:0{Z1:1K10:l2:^-1/RN1:l2:s14:pK6:\
+l2:+s2:pK2:s9:p0s10:pN2:l5:K2:}Z3:l9:K2:*s9:pl5:cRs5:pJ2:N3:N4:\
+l5:K.5:{Z5:l9:K2:*s9:pl5:cRs5:pJ4:N5:l5:1-l5:1+/s12:s13:pl12:\
+l12:*s11:pK3:s10:pN7:1B8:J6:N9:l10:K2:+s10:pJ7:N8:l12:l11:*s12:\
+l10:/s8:pl8:0=Z10:l9:l13:*s13:pl14:s2:pl13:1/RN10:l13:l8:+s13:\
+pJ9:N6:0R]@r\
+@iF3,5.8,10,11,12,15,13,14[l2:s14:pK1.1:l14:*K2:+s2:p1C4,0:s13:\
+pl5:0<Z1:1s11:pl5:ns5:pN1:0s2:pl5:l13:/K2:+K4:/s12:pl5:K4:l12:\
+*l13:*-s5:pl12:K2:%Z2:l5:ns5:pN2:l14:K2:+s2:pl5:s8:s13:pl5:nl5:\
+*s15:pK3:s10:pN4:1B5:J3:N6:l10:K2:+s10:pJ4:N5:l8:l15:l10:l10:\
+1-*/*s8:pl8:0=Z7:l14:s2:pl11:Z8:l13:n1/RN8:l13:1/RN7:l13:l8:+\
+s13:pJ6:N3:0R]@r\
+@iF5,5.13[l2:1+s2:pl5:1C4,0:K2:*+C3,0:s13:pl2:1-s2:pl13:1/R0R]\
+@r\
+@iF4,5.6,8,9,10,11,12,15,13,14[1s11:pl5:0<Z1:1ns11:pl5:ns5:pN1:\
+l5:1=Z2:l2:K25:{Z3:K.7853981633974483096156608:l11:/RN3:l2:K40\
+:{Z4:K.7853981633974483096156608458198757210492:l11:/RN4:l2:K\
+60:{Z5:K.785398163397448309615660845819875721049292349843776455243736\
+:l11:/RN5:N2:l5:K.2:=Z6:l2:K25:{Z7:K.1973955598498807583700497\
+:l11:/RN7:l2:K40:{Z8:K.1973955598498807583700497651947902934475\
+:l11:/RN8:l2:K60:{Z9:K.197395559849880758370049765194790293447585103787852101517688\
+:l11:/RN9:N6:l2:s14:pl5:K.2:>Z10:l14:K5:+s2:pK.2:C4,0:s6:pN10:\
+l14:K3:+s2:pN11:l5:K.2:>Z12:l9:1+s9:pl5:K.2:-1l5:K.2:*+/s5:pJ11:N12:\
+l5:s12:s13:pl5:nl5:*s15:pK3:s10:pN14:1B15:J13:N16:l10:K2:+s10:\
+pJ14:N15:l12:l15:*s12:l10:/s8:pl8:0=Z17:l14:s2:pl9:l6:*l13:+l11:\
+/RN17:l13:l8:+s13:pJ16:N13:0R]@r\
+@iF6,12,5.6,7,8,9,10,11,15,13,14[l2:s14:p0s2:pl12:1/s12:pl12:\
+0<Z1:l12:ns12:pl12:K2:%1=Z2:1s11:pN2:N1:1s9:pK2:s10:pN4:l10:l12:\
+{B5:J3:N6:l10:i10:pJ4:N5:l9:l10:*s9:pJ6:N3:K1.5:l14:*s2:pl5:l12:\
+^K2:l12:^/l9:/s9:p1s8:s13:pl5:nl5:*K4:/s15:pK1.5:l14:*s2:p1s10:\
+pN8:1B9:J7:N10:l10:i10:pJ8:N9:l8:l15:*l10:/l12:l10:+/s8:pl8:0\
+=Z11:l14:s2:pl11:Z12:l9:nl13:*1/RN12:l9:l13:*1/RN11:l13:l8:+s13:\
+pJ10:N7:0R]@r"
diff --git a/contrib/bc/bc/load.c b/contrib/bc/bc/load.c
new file mode 100644
index 000000000000..055a7c05c960
--- /dev/null
+++ b/contrib/bc/bc/load.c
@@ -0,0 +1,348 @@
+/* load.c: This code "loads" code into the code segments. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+#include "bcdefs.h"
+#include "global.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 (byte)
+ char byte;
+{
+ int seg, offset, func;
+
+ /* If there was an error, don't continue. */
+ if (had_error) return;
+
+ /* Calculate the segment and offset. */
+ seg = load_adr.pc_addr >> BC_SEG_LOG;
+ offset = load_adr.pc_addr++ % BC_SEG_SIZE;
+ func = load_adr.pc_func;
+
+ if (seg >= BC_MAX_SEGS)
+ {
+ yyerror ("Function too big.");
+ return;
+ }
+
+ if (functions[func].f_body[seg] == NULL)
+ functions[func].f_body[seg] = (char *) bc_malloc (BC_SEG_SIZE);
+
+ /* Store the byte. */
+ functions[func].f_body[seg][offset] = byte;
+ functions[func].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)
+ char **str;
+{ int val = 0;
+ char neg = FALSE;
+
+ if (**str == '-')
+ {
+ neg = TRUE;
+ (*str)++;
+ }
+ while (isdigit(**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)
+ char *code;
+{
+ char *str;
+ long ap_name; /* auto or parameter name. */
+ long label_no;
+ long vaf_name; /* variable, array or function number. */
+ long func;
+ 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/contrib/bc/bc/main.c b/contrib/bc/bc/main.c
new file mode 100644
index 000000000000..0189e1904053
--- /dev/null
+++ b/contrib/bc/bc/main.c
@@ -0,0 +1,323 @@
+/* main.c: The main program for bc. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+#include "bcdefs.h"
+#include <signal.h>
+#include "global.h"
+#include "proto.h"
+#include "getopt.h"
+
+
+/* Variables for processing multiple files. */
+char first_file;
+extern FILE *yyin;
+
+/* Points to the last node in the file name list for easy adding. */
+static file_node *last = NULL;
+
+#ifdef READLINE
+/* Readline support. */
+extern char *rl_readline_name;
+extern FILE *rl_instream;
+#endif
+
+/* long option support */
+static struct option long_options[] =
+{
+ {"compile", 0, &compile_only, TRUE},
+ {"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}
+};
+
+
+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, "lciqsvw", long_options, &long_index);
+
+ if (optch == EOF) /* End of arguments. */
+ break;
+
+ switch (optch)
+ {
+ case 'c': /* compile only */
+ compile_only = TRUE;
+ break;
+
+ case 'l': /* math lib */
+ use_math = TRUE;
+ break;
+
+ case 'i': /* force interactive */
+ interactive = 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. */
+ printf ("%s\n", BC_VERSION);
+ exit (0);
+ break;
+
+ case 'w': /* Non standard features give warnings. */
+ warn_not_std = TRUE;
+ break;
+ }
+ }
+
+ /* 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;
+ char *env_argv[30];
+ int env_argc;
+
+ /* Initialize many variables. */
+ compile_only = FALSE;
+ use_math = FALSE;
+ warn_not_std = FALSE;
+ std_only = FALSE;
+ if (isatty(0) && isatty(1))
+ interactive = TRUE;
+ else
+ interactive = FALSE;
+ quiet = FALSE;
+ file_names = NULL;
+
+ /* 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 < 2)
+ 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);
+
+#ifdef READLINE
+ /* 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");
+
+ 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)
+ {
+#ifdef BC_MATH_FILE
+ /* Make the first file be the math library. */
+ new_file = fopen (BC_MATH_FILE, "r");
+ use_math = FALSE;
+ if (new_file != NULL)
+ {
+ new_yy_file (new_file);
+ return TRUE;
+ }
+ else
+ {
+ fprintf (stderr, "Math Library unavailable.\n");
+ exit (1);
+ }
+#else
+ /* Load the code from a precompiled version of the math libarary. */
+ extern char libmath[];
+ 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);
+ load_code (libmath);
+#endif
+ }
+
+ /* 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;
+{
+ printf ("\n(interrupt) use quit to exit.\n");
+ signal (SIGINT, use_quit);
+}
diff --git a/contrib/bc/bc/sbc.y b/contrib/bc/bc/sbc.y
new file mode 100644
index 000000000000..9e1bd339eadc
--- /dev/null
+++ b/contrib/bc/bc/sbc.y
@@ -0,0 +1,446 @@
+%{
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ 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> NEWLINE 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)
+ {
+ printf ("s%s\n", BC_VERSION);
+ welcome();
+ }
+ }
+ | program input_item
+ ;
+input_item : semicolon_list NEWLINE
+ { run_code(); }
+ | function
+ { run_code(); }
+ | error NEWLINE
+ {
+ yyerrok;
+ init_gen() ;
+ }
+ ;
+semicolon_list : /* empty */
+ { $$ = 0; }
+ | statement_or_error
+ | semicolon_list ';' statement_or_error
+ | semicolon_list ';'
+ ;
+statement_list : /* empty */
+ { $$ = 0; }
+ | statement
+ | statement_list NEWLINE
+ | statement_list NEWLINE 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 ')' '{'
+ NEWLINE opt_auto_define_list
+ {
+ check_params ($4,$8);
+ sprintf (genstr, "F%d,%s.%s[", lookup($2,FUNCT),
+ arg_str ($4), arg_str ($8));
+ generate (genstr);
+ free_args ($4);
+ free_args ($8);
+ $1 = next_label;
+ next_label = 0;
+ }
+ statement_list NEWLINE '}'
+ {
+ 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 NEWLINE
+ { $$ = $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)
+ {
+ sprintf (genstr, "C%d,%s:", lookup($1,FUNCT),
+ arg_str ($3));
+ 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/contrib/bc/bc/scan.c b/contrib/bc/bc/scan.c
new file mode 100644
index 000000000000..43ad82020ecb
--- /dev/null
+++ b/contrib/bc/bc/scan.c
@@ -0,0 +1,1612 @@
+/* A lexical scanner generated by flex */
+
+/* scanner skeleton version:
+ * $Header: /usr/fsys/odin/a/vern/flex/RCS/flex.skel,v 2.16 90/08/03 14:09:36 vern Exp $
+ */
+
+#define FLEX_SCANNER
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <osfcn.h>
+
+/* use prototypes in function declarations */
+#define YY_USE_PROTOS
+
+/* the "const" storage-class-modifier is valid */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#ifdef __STDC__
+
+#ifdef __GNUC__
+#include <stddef.h>
+void *malloc( size_t );
+void free( void* );
+#else
+#include <stdlib.h>
+#endif /* __GNUC__ */
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+
+#ifdef __TURBOC__
+#define YY_USE_CONST
+#endif
+
+
+#ifndef YY_USE_CONST
+#define const
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+/* we can't get here if it's an ANSI C compiler, or a C++ compiler,
+ * so it's got to be a K&R compiler, and therefore there's no standard
+ * place from which to include these definitions
+ */
+/* char *malloc();
+int free(); */
+int read();
+#endif
+
+
+/* amount of stuff to slurp up with each read */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* returned upon end-of-file */
+#define YY_END_TOK 0
+
+/* copy whatever the last rule matched to the standard output */
+
+/* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */
+/* this used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite()
+ */
+#define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout )
+
+/* gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#define YY_INPUT(buf,result,max_size) \
+ if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
+ YY_FATAL_ERROR( "read() in flex scanner failed" );
+#define YY_NULL 0
+
+/* 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.
+ */
+#define yyterminate() return ( YY_NULL )
+
+/* report a fatal error */
+
+/* The funky do-while is used to turn this macro definition into
+ * a single C statement (which needs a semi-colon terminator).
+ * This avoids problems with code like:
+ *
+ * if ( something_happens )
+ * YY_FATAL_ERROR( "oops, the something happened" );
+ * else
+ * everything_okay();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the YY_FATAL_ERROR() call.
+ */
+
+#define YY_FATAL_ERROR(msg) \
+ do \
+ { \
+ (void) fputs( msg, stderr ); \
+ (void) putc( '\n', stderr ); \
+ exit( 1 ); \
+ } \
+ while ( 0 )
+
+/* default yywrap function - always treat EOF as an EOF */
+#define yywrap() 1
+
+/* 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 *
+
+/* 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 \
+ do \
+ { \
+ yy_init_buffer( yy_current_buffer, yyin ); \
+ yy_load_buffer_state(); \
+ } \
+ while ( 0 )
+
+/* default declaration of generated scanner - a define so the user can
+ * easily add parameters
+ */
+#define YY_DECL int yylex YY_PROTO(( void ))
+
+/* code executed at the end of each rule */
+#define YY_BREAK break;
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */
+#endif
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+#define YY_CHAR unsigned char
+# line 1 "scan.l"
+#define INITIAL 0
+# line 2 "scan.l"
+/* scan.l: the (f)lex description file for the scanner. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+#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));
+
+#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 char rl_len = 0;
+
+/* Definitions for readline access. */
+extern FILE *rl_instream;
+_PROTOTYPE(char *readline, (char *));
+
+/* Needed here? */
+extern FILE *yyin;
+
+/* 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_line)
+ free(rl_line);
+ rl_line = readline ("");
+ if (rl_line == NULL) {
+ /* end of file */
+ *result = 0;
+ rl_len = 0;
+ return;
+ }
+ rl_len = strlen (rl_line)+1;
+ if (rl_len != 1)
+ add_history (rl_line);
+ rl_line[rl_len-1] = '\n';
+ printf ("\r");
+ 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_len -= max;
+ }
+}
+#else
+/* 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
+#define slcomment 1
+# line 141 "scan.l"
+
+/* done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext = yy_bp; \
+ yyleng = yy_cp - yy_bp; \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* return all but the first 'n' matched characters back to the input stream */
+#define yyless(n) \
+ do \
+ { \
+ /* undo effects of setting up yytext */ \
+ *yy_cp = yy_hold_char; \
+ yy_c_buf_p = yy_cp = yy_bp + n; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext )
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ YY_CHAR *yy_ch_buf; /* input buffer */
+ YY_CHAR *yy_buf_pos; /* current position in input buffer */
+
+ /* size of input buffer in bytes, not including room for EOB characters*/
+ int yy_buf_size;
+
+ /* number of characters read into yy_ch_buf, not including EOB characters */
+ int yy_n_chars;
+
+ int yy_eof_status; /* whether we've seen an EOF on this buffer */
+#define EOF_NOT_SEEN 0
+ /* "pending" happens when the EOF has been seen but there's still
+ * some text process
+ */
+#define EOF_PENDING 1
+#define EOF_DONE 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer;
+
+/* 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"
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed */
+static YY_CHAR yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+#ifndef YY_USER_INIT
+#define YY_USER_INIT
+#endif
+
+extern YY_CHAR *yytext;
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+YY_CHAR *yytext;
+int yyleng;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+#define YY_END_OF_BUFFER 45
+typedef int yy_state_type;
+static const short int yy_accept[298] =
+ { 0,
+ 0, 0, 2, 2, 45, 43, 38, 36, 30, 43,
+ 1, 31, 43, 27, 31, 27, 27, 26, 31, 42,
+ 34, 32, 34, 43, 27, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 43, 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, 38,
+ 34, 0, 41, 32, 28, 35, 42, 0, 39, 42,
+ 42, 0, 33, 37, 40, 40, 40, 40, 40, 40,
+
+ 40, 40, 40, 40, 10, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 29, 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, 42, 0, 0, 42, 0,
+ 40, 40, 40, 40, 40, 9, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 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, 40, 40, 40,
+ 17, 19, 40, 40, 20, 40, 40, 40, 40, 6,
+ 18, 40, 40, 12, 40, 40, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 5, 40, 40, 40,
+ 14, 40, 40, 15, 24, 40, 13, 40, 11, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 40, 4, 40, 7, 25, 8, 40, 2,
+ 2, 2, 2, 2, 2, 2, 40, 21, 40, 2,
+ 2, 2, 23, 22, 2, 2, 0
+
+ } ;
+
+static const YY_CHAR 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, 37, 49, 37,
+ 50, 37, 51, 52, 53, 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 const YY_CHAR yy_meta[54] =
+ { 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,
+ 1, 1, 1
+ } ;
+
+static const short int yy_base[302] =
+ { 0,
+ 0, 0, 53, 0, 525, 526, 522, 526, 503, 517,
+ 526, 501, 512, 526, 499, 95, 94, 94, 99, 105,
+ 498, 114, 497, 513, 495, 466, 468, 470, 479, 471,
+ 467, 0, 81, 102, 105, 479, 462, 458, 473, 94,
+ 104, 452, 0, 501, 526, 482, 139, 0, 481, 492,
+ 0, 479, 131, 132, 131, 125, 132, 478, 150, 477,
+ 493, 475, 160, 115, 117, 126, 130, 125, 446, 183,
+ 184, 186, 187, 123, 445, 180, 185, 192, 440, 489,
+ 526, 485, 526, 526, 526, 526, 158, 486, 526, 162,
+ 221, 485, 526, 526, 0, 440, 454, 444, 451, 437,
+
+ 437, 442, 434, 451, 0, 432, 436, 436, 447, 438,
+ 437, 195, 444, 426, 425, 433, 526, 0, 466, 0,
+ 178, 0, 0, 0, 0, 222, 464, 0, 230, 233,
+ 463, 0, 417, 65, 189, 208, 193, 205, 213, 220,
+ 214, 235, 416, 218, 224, 227, 241, 234, 237, 243,
+ 246, 231, 232, 245, 0, 275, 460, 278, 279, 459,
+ 419, 432, 412, 422, 425, 0, 409, 408, 408, 406,
+ 418, 415, 404, 408, 401, 416, 398, 406, 397, 398,
+ 403, 287, 438, 288, 437, 182, 250, 239, 270, 275,
+ 391, 266, 268, 271, 273, 274, 288, 279, 285, 281,
+
+ 299, 390, 292, 287, 293, 298, 0, 399, 400, 394,
+ 0, 0, 392, 401, 0, 385, 384, 398, 382, 0,
+ 0, 383, 395, 0, 398, 393, 376, 294, 303, 302,
+ 375, 374, 306, 312, 373, 305, 308, 313, 310, 372,
+ 371, 314, 317, 370, 335, 332, 0, 376, 384, 370,
+ 0, 379, 367, 0, 0, 371, 0, 370, 0, 362,
+ 325, 336, 322, 361, 137, 323, 360, 359, 331, 358,
+ 333, 357, 356, 0, 353, 0, 0, 0, 355, 349,
+ 343, 327, 342, 340, 334, 338, 346, 0, 238, 344,
+ 236, 339, 0, 0, 177, 102, 526, 392, 120, 395,
+
+ 398
+ } ;
+
+static const short int yy_def[302] =
+ { 0,
+ 297, 1, 297, 3, 297, 297, 297, 297, 297, 298,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 299, 299, 299, 299, 299,
+ 299, 299, 299, 299, 299, 299, 299, 299, 299, 299,
+ 299, 297, 300, 300, 297, 300, 301, 300, 300, 300,
+ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
+ 300, 300, 300, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 300, 297,
+ 297, 298, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 299, 299, 299, 299, 299, 299,
+
+ 299, 299, 299, 299, 299, 299, 299, 299, 299, 299,
+ 299, 299, 299, 299, 299, 299, 297, 300, 300, 300,
+ 301, 300, 300, 300, 300, 300, 300, 300, 300, 300,
+ 300, 300, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 300, 297, 297, 297, 297, 297,
+ 299, 299, 299, 299, 299, 299, 299, 299, 299, 299,
+ 299, 299, 299, 299, 299, 299, 299, 299, 299, 299,
+ 299, 300, 300, 300, 300, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+
+ 63, 63, 63, 63, 63, 63, 299, 299, 299, 299,
+ 299, 299, 299, 299, 299, 299, 299, 299, 299, 299,
+ 299, 299, 299, 299, 299, 299, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 299, 299, 299, 299,
+ 299, 299, 299, 299, 299, 299, 299, 299, 299, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 299, 299, 299, 299, 299, 299, 299, 63,
+ 63, 63, 63, 63, 63, 63, 299, 299, 299, 63,
+ 63, 63, 299, 299, 63, 63, 0, 297, 297, 297,
+
+ 297
+ } ;
+
+static const short int yy_nxt[580] =
+ { 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, 32,
+ 14, 42, 14, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 51, 52, 53, 51, 54, 55, 56, 57,
+ 51, 58, 59, 60, 57, 51, 61, 51, 62, 43,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 69,
+ 69, 72, 69, 69, 73, 74, 75, 76, 77, 69,
+
+ 69, 78, 69, 51, 79, 51, 86, 86, 102, 89,
+ 87, 186, 133, 84, 84, 87, 103, 88, 84, 90,
+ 93, 91, 95, 113, 93, 93, 91, 93, 92, 93,
+ 104, 115, 106, 81, 105, 128, 107, 114, 116, 93,
+ 108, 82, 125, 122, 123, 125, 129, 126, 130, 133,
+ 123, 123, 126, 130, 127, 131, 132, 137, 136, 135,
+ 132, 132, 133, 132, 133, 132, 139, 148, 138, 120,
+ 133, 283, 133, 133, 156, 132, 133, 133, 159, 156,
+ 82, 157, 122, 159, 133, 160, 133, 133, 133, 133,
+ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
+
+ 133, 133, 133, 133, 133, 133, 133, 134, 133, 133,
+ 140, 150, 142, 144, 151, 147, 143, 145, 141, 153,
+ 187, 146, 176, 227, 133, 189, 154, 133, 152, 133,
+ 133, 133, 133, 133, 133, 90, 133, 91, 182, 133,
+ 133, 177, 91, 182, 92, 183, 184, 129, 188, 130,
+ 190, 184, 133, 185, 130, 133, 131, 191, 192, 193,
+ 133, 133, 194, 195, 196, 133, 197, 133, 198, 199,
+ 201, 133, 200, 203, 133, 204, 205, 228, 133, 133,
+ 206, 133, 133, 133, 133, 229, 133, 294, 133, 202,
+ 133, 156, 133, 133, 87, 159, 156, 133, 157, 87,
+
+ 159, 88, 160, 182, 184, 230, 231, 236, 182, 184,
+ 183, 185, 232, 133, 233, 133, 234, 133, 133, 235,
+ 133, 133, 133, 237, 238, 239, 133, 240, 133, 241,
+ 243, 260, 133, 244, 133, 133, 246, 245, 261, 133,
+ 133, 133, 262, 264, 267, 133, 133, 263, 270, 133,
+ 133, 265, 133, 133, 266, 133, 268, 133, 269, 133,
+ 133, 133, 271, 272, 133, 280, 282, 281, 284, 133,
+ 133, 285, 133, 286, 133, 295, 291, 293, 133, 133,
+ 133, 133, 133, 133, 292, 133, 133, 133, 296, 133,
+ 133, 133, 82, 82, 82, 118, 290, 118, 121, 121,
+
+ 121, 289, 288, 287, 133, 133, 133, 133, 133, 133,
+ 279, 278, 277, 276, 275, 274, 273, 133, 133, 133,
+ 133, 133, 133, 133, 259, 258, 257, 256, 255, 254,
+ 253, 252, 251, 250, 249, 248, 247, 242, 133, 159,
+ 156, 226, 225, 224, 223, 222, 221, 220, 219, 218,
+ 217, 216, 215, 214, 213, 212, 211, 210, 209, 208,
+ 207, 159, 156, 133, 133, 91, 158, 119, 181, 180,
+ 179, 178, 175, 174, 173, 172, 171, 170, 169, 168,
+ 167, 166, 165, 164, 163, 162, 161, 91, 158, 83,
+ 80, 155, 149, 133, 123, 94, 120, 120, 123, 124,
+
+ 123, 120, 119, 117, 112, 111, 110, 109, 101, 100,
+ 99, 98, 97, 96, 84, 94, 81, 81, 84, 85,
+ 84, 83, 81, 80, 297, 5, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297
+ } ;
+
+static const short int yy_chk[580] =
+ { 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, 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, 134, 134, 17, 16, 18, 33, 18, 19, 20,
+ 22, 20, 299, 40, 22, 22, 20, 22, 20, 22,
+ 34, 41, 35, 22, 34, 56, 35, 40, 41, 22,
+ 35, 47, 53, 47, 56, 54, 57, 55, 57, 296,
+ 53, 54, 55, 57, 55, 57, 59, 66, 65, 64,
+ 59, 59, 64, 59, 65, 59, 68, 74, 67, 59,
+ 74, 265, 68, 66, 87, 59, 63, 67, 90, 87,
+ 121, 87, 121, 90, 265, 90, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 70, 76, 71, 72, 77, 73, 71, 72, 70, 78,
+ 135, 72, 112, 186, 295, 137, 78, 76, 77, 186,
+ 70, 71, 77, 72, 73, 91, 135, 91, 126, 78,
+ 137, 112, 91, 126, 91, 126, 129, 130, 136, 130,
+ 138, 129, 138, 129, 130, 136, 130, 139, 140, 141,
+ 139, 141, 142, 144, 145, 144, 146, 140, 147, 148,
+ 150, 145, 149, 151, 146, 152, 153, 187, 152, 153,
+ 154, 148, 142, 291, 149, 188, 188, 289, 147, 150,
+ 150, 156, 154, 151, 158, 159, 156, 187, 156, 158,
+
+ 159, 158, 159, 182, 184, 189, 190, 196, 182, 184,
+ 182, 184, 192, 192, 193, 193, 194, 189, 194, 195,
+ 195, 196, 190, 197, 198, 199, 198, 200, 200, 201,
+ 203, 228, 199, 204, 204, 197, 206, 205, 229, 203,
+ 205, 228, 230, 234, 238, 206, 201, 233, 243, 230,
+ 229, 236, 236, 233, 237, 237, 239, 239, 242, 234,
+ 238, 242, 245, 246, 243, 261, 263, 262, 266, 263,
+ 266, 269, 261, 271, 282, 290, 282, 287, 269, 246,
+ 271, 285, 245, 262, 286, 286, 292, 284, 292, 283,
+ 281, 290, 298, 298, 298, 300, 280, 300, 301, 301,
+
+ 301, 279, 275, 273, 272, 270, 268, 267, 264, 260,
+ 258, 256, 253, 252, 250, 249, 248, 244, 241, 240,
+ 235, 232, 231, 227, 226, 225, 223, 222, 219, 218,
+ 217, 216, 214, 213, 210, 209, 208, 202, 191, 185,
+ 183, 181, 180, 179, 178, 177, 176, 175, 174, 173,
+ 172, 171, 170, 169, 168, 167, 165, 164, 163, 162,
+ 161, 160, 157, 143, 133, 131, 127, 119, 116, 115,
+ 114, 113, 111, 110, 109, 108, 107, 106, 104, 103,
+ 102, 101, 100, 99, 98, 97, 96, 92, 88, 82,
+ 80, 79, 75, 69, 62, 61, 60, 58, 52, 50,
+
+ 49, 46, 44, 42, 39, 38, 37, 36, 31, 30,
+ 29, 28, 27, 26, 25, 24, 23, 21, 15, 13,
+ 12, 10, 9, 7, 5, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297, 297,
+ 297, 297, 297, 297, 297, 297, 297, 297, 297
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static YY_CHAR *yy_last_accepting_cpos;
+
+/* 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
+
+/* these variables are all declared out here so that section 3 code can
+ * manipulate them
+ */
+/* points to current character in buffer */
+static YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0;
+static int yy_init = 1; /* 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;
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yyunput YY_PROTO(( YY_CHAR c, YY_CHAR *buf_ptr ));
+void yyrestart YY_PROTO(( FILE *input_file ));
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+
+#define yy_new_buffer yy_create_buffer
+
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register YY_CHAR *yy_cp, *yy_bp;
+ register int yy_act;
+
+
+
+ if ( yy_init )
+ {
+ YY_USER_INIT;
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( yy_current_buffer )
+ yy_init_buffer( yy_current_buffer, yyin );
+ else
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+
+ yy_init = 0;
+ }
+
+ 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_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 = yy_def[yy_current_state];
+ if ( yy_current_state >= 298 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 526 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+ YY_USER_ACTION;
+
+do_action: /* this label is used only to access EOF actions */
+
+
+ switch ( yy_act )
+ {
+ case 0: /* must backtrack */
+ /* 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:
+# line 142 "scan.l"
+{
+ if (!std_only)
+ BEGIN(slcomment);
+ else
+ yyerror ("illegal character: #");
+ }
+ YY_BREAK
+case 2:
+# line 148 "scan.l"
+{ BEGIN(INITIAL); }
+ YY_BREAK
+case 3:
+# line 149 "scan.l"
+{ line_no++; BEGIN(INITIAL); return(NEWLINE); }
+ YY_BREAK
+case 4:
+# line 150 "scan.l"
+return(Define);
+ YY_BREAK
+case 5:
+# line 151 "scan.l"
+return(Break);
+ YY_BREAK
+case 6:
+# line 152 "scan.l"
+return(Quit);
+ YY_BREAK
+case 7:
+# line 153 "scan.l"
+return(Length);
+ YY_BREAK
+case 8:
+# line 154 "scan.l"
+return(Return);
+ YY_BREAK
+case 9:
+# line 155 "scan.l"
+return(For);
+ YY_BREAK
+case 10:
+# line 156 "scan.l"
+return(If);
+ YY_BREAK
+case 11:
+# line 157 "scan.l"
+return(While);
+ YY_BREAK
+case 12:
+# line 158 "scan.l"
+return(Sqrt);
+ YY_BREAK
+case 13:
+# line 159 "scan.l"
+return(Scale);
+ YY_BREAK
+case 14:
+# line 160 "scan.l"
+return(Ibase);
+ YY_BREAK
+case 15:
+# line 161 "scan.l"
+return(Obase);
+ YY_BREAK
+case 16:
+# line 162 "scan.l"
+return(Auto);
+ YY_BREAK
+case 17:
+# line 163 "scan.l"
+return(Else);
+ YY_BREAK
+case 18:
+# line 164 "scan.l"
+return(Read);
+ YY_BREAK
+case 19:
+# line 165 "scan.l"
+return(Halt);
+ YY_BREAK
+case 20:
+# line 166 "scan.l"
+return(Last);
+ YY_BREAK
+case 21:
+# line 167 "scan.l"
+{
+#ifdef READLINE
+ return(History);
+#else
+ yylval.s_value = strcopyof(yytext); return(NAME);
+#endif
+ }
+ YY_BREAK
+case 22:
+# line 175 "scan.l"
+return(Warranty);
+ YY_BREAK
+case 23:
+# line 176 "scan.l"
+return(Continue);
+ YY_BREAK
+case 24:
+# line 177 "scan.l"
+return(Print);
+ YY_BREAK
+case 25:
+# line 178 "scan.l"
+return(Limits);
+ YY_BREAK
+case 26:
+# line 179 "scan.l"
+{
+#ifdef DOT_IS_LAST
+ return(Last);
+#else
+ yyerror ("illegal character: %s",yytext);
+#endif
+ }
+ YY_BREAK
+case 27:
+# line 186 "scan.l"
+{ yylval.c_value = yytext[0];
+ return((int)yytext[0]); }
+ YY_BREAK
+case 28:
+# line 188 "scan.l"
+{ return(AND); }
+ YY_BREAK
+case 29:
+# line 189 "scan.l"
+{ return(OR); }
+ YY_BREAK
+case 30:
+# line 190 "scan.l"
+{ return(NOT); }
+ YY_BREAK
+case 31:
+# line 191 "scan.l"
+{ yylval.c_value = yytext[0]; return((int)yytext[0]); }
+ YY_BREAK
+case 32:
+# line 192 "scan.l"
+{ yylval.c_value = yytext[0]; return(ASSIGN_OP); }
+ YY_BREAK
+case 33:
+# line 193 "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 34:
+# line 207 "scan.l"
+{ yylval.s_value = strcopyof(yytext); return(REL_OP); }
+ YY_BREAK
+case 35:
+# line 208 "scan.l"
+{ yylval.c_value = yytext[0]; return(INCR_DECR); }
+ YY_BREAK
+case 36:
+# line 209 "scan.l"
+{ line_no++; return(NEWLINE); }
+ YY_BREAK
+case 37:
+# line 210 "scan.l"
+{ line_no++; /* ignore a "quoted" newline */ }
+ YY_BREAK
+case 38:
+# line 211 "scan.l"
+{ /* ignore spaces and tabs */ }
+ YY_BREAK
+case 39:
+# line 212 "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 40:
+# line 233 "scan.l"
+{ yylval.s_value = strcopyof(yytext); return(NAME); }
+ YY_BREAK
+case 41:
+# line 234 "scan.l"
+{
+ unsigned 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 42:
+# line 246 "scan.l"
+{
+ unsigned 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 43:
+# line 273 "scan.l"
+{
+ if (yytext[0] < ' ')
+ yyerror ("illegal character: ^%c",yytext[0] + '@');
+ else
+ if (yytext[0] > '~')
+ yyerror ("illegal character: \\%3d", (int) yytext[0]);
+ else
+ yyerror ("illegal character: %s",yytext);
+ }
+ YY_BREAK
+case 44:
+# line 282 "scan.l"
+ECHO;
+ YY_BREAK
+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 = yy_cp - yytext - 1;
+
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+
+ /* 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 yyinput().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* this was really a NUL */
+ {
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext + 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 + 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
+ {
+ 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 + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF((yy_start - 1) / 2);
+ 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 + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+#ifdef FLEX_DEBUG
+ printf( "action # %d\n", yy_act );
+#endif
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ }
+ }
+ }
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * synopsis
+ * int yy_get_next_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()
+
+ {
+ register YY_CHAR *dest = yy_current_buffer->yy_ch_buf;
+ register YY_CHAR *source = yytext - 1; /* copy prev. char, too */
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ /* try to read more data */
+
+ /* first move last chars to start of buffer */
+ number_to_move = yy_c_buf_p - yytext;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ else if ( num_to_read <= 0 )
+ YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" );
+
+ /* read in more data */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move == 1 )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yy_current_buffer->yy_eof_status = EOF_DONE;
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_eof_status = EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ /* yytext begins at the second character in yy_ch_buf; the first
+ * character is the one which preceded it before reading in the latest
+ * buffer; it needs to be kept around in case it's a newline, so
+ * yy_get_previous_state() will have with '^' rules active
+ */
+
+ yytext = &yy_current_buffer->yy_ch_buf[1];
+
+ return ( ret_val );
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached
+ *
+ * synopsis
+ * yy_state_type yy_get_previous_state();
+ */
+
+static yy_state_type yy_get_previous_state()
+
+ {
+ register yy_state_type yy_current_state;
+ register YY_CHAR *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[*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 = yy_def[yy_current_state];
+ if ( yy_current_state >= 298 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + 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 );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( register yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+register yy_state_type yy_current_state;
+#endif
+
+ {
+ register int yy_is_jam;
+ register YY_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 = yy_def[yy_current_state];
+ if ( yy_current_state >= 298 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 297);
+
+ return ( yy_is_jam ? 0 : yy_current_state );
+ }
+
+
+#ifdef YY_USE_PROTOS
+static void yyunput( YY_CHAR c, register YY_CHAR *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+YY_CHAR c;
+register YY_CHAR *yy_bp;
+#endif
+
+ {
+ register YY_CHAR *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */
+ register YY_CHAR *dest =
+ &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2];
+ register YY_CHAR *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += dest - source;
+ yy_bp += dest - source;
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ if ( yy_cp > yy_bp && yy_cp[-1] == '\n' )
+ yy_cp[-2] = '\n';
+
+ *--yy_cp = c;
+
+ /* note: the formal parameter *must* be called "yy_bp" for this
+ * macro to now work correctly
+ */
+ YY_DO_BEFORE_ACTION; /* set up yytext again */
+ }
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+
+ {
+ int c;
+ YY_CHAR *yy_cp = yy_c_buf_p;
+
+ *yy_cp = 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->yy_ch_buf[yy_n_chars] )
+ /* this was really a NUL */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ yytext = yy_c_buf_p;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ {
+ yy_c_buf_p = yytext + YY_MORE_ADJ;
+ return ( EOF );
+ }
+
+ YY_NEW_FILE;
+
+#ifdef __cplusplus
+ return ( yyinput() );
+#else
+ return ( input() );
+#endif
+ }
+ break;
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext + YY_MORE_ADJ;
+ break;
+
+ case EOB_ACT_LAST_MATCH:
+#ifdef __cplusplus
+ YY_FATAL_ERROR( "unexpected last match in yyinput()" );
+#else
+ YY_FATAL_ERROR( "unexpected last match in input()" );
+#endif
+ }
+ }
+ }
+
+ c = *yy_c_buf_p;
+ yy_hold_char = *++yy_c_buf_p;
+
+ return ( c );
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+
+ {
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+
+ {
+ 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->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = 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;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) malloc( 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 = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) );
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ yy_init_buffer( b, file );
+
+ return ( b );
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+ {
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ free( (char *) b->yy_ch_buf );
+ free( (char *) b );
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+ {
+ b->yy_input_file = file;
+
+ /* we put in the '\n' and start reading from [1] so that an
+ * initial match-at-newline will be true.
+ */
+
+ b->yy_ch_buf[0] = '\n';
+ b->yy_n_chars = 1;
+
+ /* 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[1] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[1];
+
+ b->yy_eof_status = EOF_NOT_SEEN;
+ }
+# line 282 "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/contrib/bc/bc/scan.l b/contrib/bc/bc/scan.l
new file mode 100644
index 000000000000..8b5b25dc142c
--- /dev/null
+++ b/contrib/bc/bc/scan.l
@@ -0,0 +1,293 @@
+%{
+/* scan.l: the (f)lex description file for the scanner. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+#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));
+
+#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 char rl_len = 0;
+
+/* Definitions for readline access. */
+extern FILE *rl_instream;
+_PROTOTYPE(char *readline, (char *));
+
+/* Needed here? */
+extern FILE *yyin;
+
+/* 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_line)
+ free(rl_line);
+ rl_line = readline ("");
+ if (rl_line == NULL) {
+ /* end of file */
+ *result = 0;
+ rl_len = 0;
+ return;
+ }
+ rl_len = strlen (rl_line)+1;
+ if (rl_len != 1)
+ add_history (rl_line);
+ rl_line[rl_len-1] = '\n';
+ printf ("\r");
+ 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_len -= max;
+ }
+}
+#else
+/* 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(NEWLINE); }
+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);
+halt return(Halt);
+last return(Last);
+history {
+#ifdef READLINE
+ return(History);
+#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(NEWLINE); }
+\\\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); }
+\"[^\"]*\" {
+ unsigned 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)* {
+ unsigned 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: \\%3d", (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/contrib/bc/bc/storage.c b/contrib/bc/bc/storage.c
new file mode 100644
index 000000000000..781fe96f6617
--- /dev/null
+++ b/contrib/bc/bc/storage.c
@@ -0,0 +1,1070 @@
+/* storage.c: Code and data storage manipulations. This includes labels. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+#include "bcdefs.h"
+#include "global.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] = "(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;
+#ifdef READLINE
+ n_history = -1; /* no limit. */
+#endif
+ c_code = FALSE;
+ 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 indx1, indx2;
+ 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 (indx1 = 0; indx1 < old_count; indx1++)
+ {
+ functions[indx1] = old_f[indx1];
+ f_names[indx1] = old_names[indx1];
+ }
+
+ /* Initialize the new ones. */
+ for (; indx1 < f_count; indx1++)
+ {
+ f = &functions[indx1];
+ f->f_defined = FALSE;
+ for (indx2 = 0; indx2 < BC_MAX_SEGS; indx2++)
+ f->f_body [indx2] = NULL;
+ 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];
+
+ /* 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];
+
+
+ /* 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)
+ char func;
+{
+ bc_function *f;
+ int indx;
+ bc_label_group *lg;
+
+ /* Set the pointer to the function. */
+ f = &functions[func];
+ f->f_defined = FALSE;
+
+ /* Clear the code segments. */
+ for (indx = 0; indx < BC_MAX_SEGS; indx++)
+ {
+ if (f->f_body[indx] != NULL)
+ {
+ free (f->f_body[indx]);
+ f->f_body[indx] = NULL;
+ }
+ }
+
+ 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);
+ }
+ 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;
+ 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 = 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));
+ 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, index)
+ int var_index;
+ long index;
+{
+ 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] = index & NODE_MASK;
+ ix = index >> 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] = 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] = 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)
+ {
+ free_num(&var_ptr->v_value);
+ var_ptr->v_value = copy_num (ex_stack->s_num);
+ }
+ }
+ else
+ {
+ /* It is a special variable... */
+ toobig = FALSE;
+ if (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;
+#ifdef READLINE
+ case 3:
+ temp = -1;
+ break;
+#endif
+ }
+ }
+ else
+ {
+ temp = num2long (ex_stack->s_num);
+ if (!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;
+
+#ifdef READLINE
+ case 3:
+ if (toobig)
+ {
+ temp = -1;
+ rt_warn ("history too large, set to unlimited");
+ unstifle_history ();
+ }
+ else
+ {
+ n_history = temp;
+ if (temp == -1)
+ unstifle_history ();
+ else
+ stifle_history (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 index;
+
+ if (!check_stack(2)) return;
+ index = num2long (ex_stack->s_next->s_num);
+ if (index < 0 || index > BC_DIM_MAX ||
+ (index == 0 && !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, index);
+ if (num_ptr != NULL)
+ {
+ free_num (num_ptr);
+ *num_ptr = copy_num (ex_stack->s_num);
+ free_num (&ex_stack->s_next->s_num);
+ ex_stack->s_next->s_num = ex_stack->s_num;
+ 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_);
+ int2num (&ex_stack->s_num, i_base);
+ break;
+
+ case 1:
+ /* Special variable obase. */
+ push_copy (_zero_);
+ int2num (&ex_stack->s_num, o_base);
+ break;
+
+ case 2:
+ /* Special variable scale. */
+ push_copy (_zero_);
+ int2num (&ex_stack->s_num, scale);
+ break;
+
+#ifdef READLINE
+ case 3:
+ /* Special variable history. */
+ push_copy (_zero_);
+ 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 index;
+
+ if (!check_stack(1)) return;
+ index = num2long (ex_stack->s_num);
+ if (index < 0 || index > BC_DIM_MAX ||
+ (index == 0 && !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, index);
+ 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;
+
+#ifdef READLINE
+ case 3: /* history */
+ n_history--;
+ if (n_history > 0)
+ stifle_history (n_history);
+ else
+ {
+ n_history = -1;
+ rt_warn ("history is negative, set to unlimited");
+ unstifle_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)
+ char var_name;
+{
+ bc_num *num_ptr;
+ long index;
+
+ /* It is an array variable. */
+ if (!check_stack (1)) return;
+ index = num2long (ex_stack->s_num);
+ if (index < 0 || index > BC_DIM_MAX ||
+ (index == 0 && !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, index);
+ 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;
+
+#ifdef READLINE
+ case 3: /* history */
+ n_history++;
+ if (n_history > 0)
+ stifle_history (n_history);
+ else
+ {
+ n_history = -1;
+ rt_warn ("history set to unlimited");
+ unstifle_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 index;
+
+ if (!check_stack (1)) return;
+ index = num2long (ex_stack->s_num);
+ if (index < 0 || index > BC_DIM_MAX ||
+ (index == 0 && !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, index);
+ 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];
+ 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++)
+ 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;
+ 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] = 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 (pc, func)
+ program_counter *pc;
+ 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(pc)) != ':')
+ {
+ 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;
+ 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) 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/contrib/bc/bc/util.c b/contrib/bc/bc/util.c
new file mode 100644
index 000000000000..514df266a144
--- /dev/null
+++ b/contrib/bc/bc/util.c
@@ -0,0 +1,859 @@
+/* util.c: Utility routines for bc. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ You may contact the author by:
+ e-mail: phil@cs.wwu.edu
+ us-mail: Philip A. Nelson
+ Computer Science Department, 9062
+ Western Washington University
+ Bellingham, WA 98226-9062
+
+*************************************************************************/
+
+
+#include "bcdefs.h"
+#ifndef VARARGS
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "global.h"
+#include "proto.h"
+
+
+/* strcopyof mallocs new memory and copies a string to to the new
+ memory. */
+
+char *
+strcopyof (str)
+ 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;
+ }
+ }
+}
+
+
+/* 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;
+}
+
+
+/* generate code STR for the machine. */
+
+void
+generate (str)
+ 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)
+ char ch;
+{
+ if (ch == '\n')
+ {
+ out_col = 0;
+ putchar ('\n');
+ }
+ else
+ {
+ out_col++;
+ if (out_col == line_size-1)
+ {
+ 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)
+ char ch;
+{
+ if (ch == '\n')
+ {
+ out_col = 0;
+ putchar ('\n');
+ }
+ else
+ {
+ if (!std_only)
+ {
+ out_col++;
+ if (out_col == line_size-1)
+ {
+ 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;
+ 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 (FALSE);
+ 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 (FALSE);
+ 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++;
+ a_names[id->a_name] = name;
+ if (id->a_name < MAX_STORE)
+ {
+ if (id->a_name >= a_count)
+ more_arrays ();
+ return (-id->a_name);
+ }
+ yyerror ("Too many array variables");
+ exit (1);
+
+ case FUNCT:
+ case FUNCTDEF:
+ if (id->f_name != 0)
+ {
+ 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++;
+ f_names[id->f_name] = name;
+ if (id->f_name < MAX_STORE)
+ {
+ if (id->f_name >= f_count)
+ more_functions ();
+ 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++;
+ v_names[id->v_name - 1] = name;
+ if (id->v_name <= MAX_STORE)
+ {
+ if (id->v_name >= v_count)
+ more_variables ();
+ return (id->v_name);
+ }
+ yyerror ("Too many variables");
+ exit (1);
+ }
+}
+
+
+/* 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 warranty information. */
+
+void
+warranty(prefix)
+ char *prefix;
+{
+ printf ("\n%s%s\n\n", prefix, BC_VERSION);
+ printf ("%s%s%s%s%s%s%s%s%s%s%s",
+" 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 the Free Software\n",
+" Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n\n");
+}
+
+/* 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 ("MAX code = %ld\n", (long) BC_MAX_SEGS * (long) BC_SEG_SIZE);
+ printf ("multiply digits = %ld\n", (long) LONG_MAX / (long) 90);
+ 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. */
+
+char *
+bc_malloc (size)
+ int size;
+{
+ char *ptr;
+
+ ptr = (char *) 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 (char *str, ...)
+#else
+void
+yyerror (str)
+ char *str;
+#endif
+#else
+void
+yyerror (str, va_alist)
+ char *str;
+#endif
+{
+ 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 (char *mesg, ...)
+#else
+void
+warn (mesg)
+ char *mesg;
+#endif
+#else
+void
+warn (mesg, va_alist)
+ char *mesg;
+#endif
+{
+ 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: ",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 (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 (func=%s, adr=%d): %s\n",
+ f_names[pc.pc_func], pc.pc_addr, error_mesg);
+ 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 (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 (func=%s, adr=%d): %s\n",
+ f_names[pc.pc_func], pc.pc_addr, error_mesg);
+}
diff --git a/contrib/bc/config.h.in b/contrib/bc/config.h.in
new file mode 100644
index 000000000000..2f3aa473b786
--- /dev/null
+++ b/contrib/bc/config.h.in
@@ -0,0 +1,68 @@
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define if you don't have vprintf but do have _doprnt. */
+#undef HAVE_DOPRNT
+
+/* Define if you have the vprintf function. */
+#undef HAVE_VPRINTF
+
+/* Define if on MINIX. */
+#undef _MINIX
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if lex declares yytext as a char * by default, not a char[]. */
+#undef YYTEXT_POINTER
+
+/* PACKAGE name */
+#undef PACKAGE
+
+/* Package VERSION number */
+#undef VERSION
+
+/* define if the math lib is to be loaded from a file. */
+#undef BC_MATH_FILE
+
+/* Define to use the readline library. */
+#undef READLINE
+
+/* Define to `size_t' if <sys/types.h> and <stddef.h> don't define. */
+#undef ptrdiff_t
+
+/* Define if you have the isgraph function. */
+#undef HAVE_ISGRAPH
+
+/* Define if you have the <lib.h> header file. */
+#undef HAVE_LIB_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
diff --git a/contrib/bc/configure b/contrib/bc/configure
new file mode 100755
index 000000000000..e487ffdbeee8
--- /dev/null
+++ b/contrib/bc/configure
@@ -0,0 +1,2315 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-readline support fancy command input editing"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+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'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+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
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # 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 ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$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" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) 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)
+ # 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 << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --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
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$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)
+ 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 ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.12"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ 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 "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# 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
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=doc/bc.1
+
+# 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_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ 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 "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# 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 "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+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
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$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
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:554: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ for ac_prog in ginstall installbsd scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ # OSF/1 installbsd also uses dspmsg, but is usable.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+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 "$ac_t""$INSTALL" 1>&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_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+
+PACKAGE=bc
+
+VERSION=1.04
+
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:620: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# 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 conftestfile 2> /dev/null`
+ if test "" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+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"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:667: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+if (aclocal --version) > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:679: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+if (autoconf --version) > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:691: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+if (automake --version) > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:703: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+if (autoheader --version) > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:715: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+if (makeinfo --version) > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:727: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 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 conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:760: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:789: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ ac_prog_rejected=no
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+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 $# -gt 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
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:837: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 847 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:851: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:871: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:876: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:885: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:900: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:928: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 943 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:949: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 960 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:966: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+ac_safe=`echo "minix/config.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6
+echo "configure:990: checking for minix/config.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 995 "configure"
+#include "confdefs.h"
+#include <minix/config.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1000: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ MINIX=yes
+else
+ echo "$ac_t""no" 1>&6
+MINIX=
+fi
+
+if test "$MINIX" = yes; then
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define _POSIX_1_SOURCE 2
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define _MINIX 1
+EOF
+
+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 $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1043: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1075: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:1108: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1116 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* 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; }
+EOF
+if { (eval echo configure:1127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking lex output file root""... $ac_c" 1>&6
+echo "configure:1150: checking lex output file root" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&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.
+echo '%%
+%%' | $LEX
+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 "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; }
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_root" 1>&6
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6
+echo "configure:1171: checking whether yytext is a pointer" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&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 <<EOF
+#line 1183 "configure"
+#include "confdefs.h"
+`cat $LEX_OUTPUT_ROOT.c`
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ ac_cv_prog_lex_yytext_pointer=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+
+echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+ cat >> confdefs.h <<\EOF
+#define YYTEXT_POINTER 1
+EOF
+
+fi
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1214: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:1247: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1255 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* 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; }
+EOF
+if { (eval echo configure:1266: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+# 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
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1299: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ for ac_prog in ginstall installbsd scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ # OSF/1 installbsd also uses dspmsg, but is usable.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+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 "$ac_t""$INSTALL" 1>&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_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1351: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:1378: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 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 conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+
+for ac_hdr in stdarg.h stddef.h stdlib.h string.h limits.h unistd.h lib.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1410: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1415 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1420: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1447: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1452 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* 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;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1501: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1522: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1527 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1535: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1552 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ 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 <<EOF
+#line 1570 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ 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 <<EOF
+#line 1591 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#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); }
+
+EOF
+if { (eval echo configure:1602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1626: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1631 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking for ptrdiff_t""... $ac_c" 1>&6
+echo "configure:1659: checking for ptrdiff_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_ptrdiff_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1664 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "ptrdiff_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_ptrdiff_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_ptrdiff_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_ptrdiff_t" 1>&6
+if test $ac_cv_type_ptrdiff_t = no; then
+ cat >> confdefs.h <<\EOF
+#define ptrdiff_t size_t
+EOF
+
+fi
+
+
+echo $ac_n "checking for vprintf""... $ac_c" 1>&6
+echo "configure:1693: checking for vprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1698 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char vprintf(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char vprintf();
+
+int main() {
+
+/* 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_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+vprintf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1721: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
+echo "configure:1745: checking for _doprnt" >&5
+if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1750 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char _doprnt(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char _doprnt();
+
+int main() {
+
+/* 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
+_doprnt();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+for ac_func in isgraph
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1800: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1805 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* 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();
+
+int main() {
+
+/* 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
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1828: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+# Check whether --with-readline or --without-readline was given.
+if test "${with_readline+set}" = set; then
+ withval="$with_readline"
+
+if test "$with_readline" = "yes" ; then
+ echo Using the readline library.
+ cat >> confdefs.h <<\EOF
+#define READLINE 1
+EOF
+
+ LIBS="$LIBS -lreadline -ltermcap"
+ bcrl=y
+else
+ bcrl=n
+fi
+
+else
+
+bcrl=n
+
+fi
+
+
+if test "$LEX" = "flex" ; then
+ LEX="flex -I8"
+else
+ if test "$bcrl" = "y" ; then
+ echo "configure: warning: readline works only with flex." 1>&2
+ fi
+fi
+
+
+SaveCFLAGS="$CFLAGS"
+CFLAGS="-g -O -I. -I$srcdir"
+echo $ac_n "checking if long strings are accepted by the C compiler""... $ac_c" 1>&6
+echo "configure:1889: checking if long strings are accepted by the C compiler" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1891 "configure"
+#include "confdefs.h"
+
+char libmath[] =
+#include "bc/libmath.h"
+;
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1902: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+echo "configure: warning: libmath.b will not be preloaded into the executable" 1>&2
+if test "${prefix}" = "NONE" ; then
+cat >> confdefs.h <<EOF
+#define BC_MATH_FILE "/usr/local/lib/libmath.b"
+EOF
+
+else
+cat >> confdefs.h <<EOF
+#define BC_MATH_FILE "${prefix}/lib/libmath.b"
+EOF
+
+fi
+fi
+rm -f conftest*
+CFLAGS="$SaveCFLAGS"
+
+
+
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+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"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# 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. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# 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) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.12"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile bc/Makefile dc/Makefile doc/Makefile lib/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@YACC@%$YACC%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g
+s%@RANLIB@%$RANLIB%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# 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_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # 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" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile bc/Makefile dc/Makefile doc/Makefile lib/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# 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='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. 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.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# 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.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/contrib/bc/configure.in b/contrib/bc/configure.in
new file mode 100644
index 000000000000..38a63e8924f6
--- /dev/null
+++ b/contrib/bc/configure.in
@@ -0,0 +1,69 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(doc/bc.1)
+AM_INIT_AUTOMAKE(bc, 1.04)
+AM_CONFIG_HEADER(config.h)
+
+AC_PROG_CC
+AC_MINIX
+dnl AC_ISC_POSIX
+
+AC_PROG_YACC
+AC_DECL_YYTEXT
+AC_PROG_LEX
+AC_PROG_INSTALL
+AC_PROG_RANLIB
+AC_PROG_MAKE_SET
+
+
+AC_CHECK_HEADERS(stdarg.h stddef.h stdlib.h string.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)
+
+
+AC_ARG_WITH(readline,[ --with-readline support fancy command input editing], [
+if test "$with_readline" = "yes" ; then
+ echo Using the readline library.
+ AC_DEFINE(READLINE,1)
+ LIBS="$LIBS -lreadline -ltermcap"
+ bcrl=y
+else
+ bcrl=n
+fi
+], [
+bcrl=n
+])
+
+if test "$LEX" = "flex" ; then
+ LEX="flex -I8"
+else
+ if test "$bcrl" = "y" ; then
+ AC_MSG_WARN(readline works only with flex.)
+ fi
+fi
+
+
+SaveCFLAGS="$CFLAGS"
+CFLAGS="-g -O -I. -I$srcdir"
+AC_MSG_CHECKING(if long strings are accepted by the C compiler)
+AC_TRY_COMPILE([
+char libmath[] =
+#include "bc/libmath.h"
+;
+],[],AC_MSG_RESULT(yes),
+AC_MSG_RESULT(no)
+AC_MSG_WARN(libmath.b will not be preloaded into the executable)
+if test "${prefix}" = "NONE" ; then
+AC_DEFINE_UNQUOTED(BC_MATH_FILE,"/usr/local/lib/libmath.b")
+else
+AC_DEFINE_UNQUOTED(BC_MATH_FILE,"${prefix}/lib/libmath.b")
+fi)
+CFLAGS="$SaveCFLAGS"
+
+
+
+AC_ARG_PROGRAM
+AC_OUTPUT(Makefile bc/Makefile dc/Makefile doc/Makefile lib/Makefile)
diff --git a/contrib/bc/dc/Makefile.am b/contrib/bc/dc/Makefile.am
new file mode 100644
index 000000000000..4de00ab339a1
--- /dev/null
+++ b/contrib/bc/dc/Makefile.am
@@ -0,0 +1,10 @@
+## 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
+
+$(PROGRAMS): $(LDADD)
diff --git a/contrib/bc/dc/Makefile.in b/contrib/bc/dc/Makefile.in
new file mode 100644
index 000000000000..44faf9437ff8
--- /dev/null
+++ b/contrib/bc/dc/Makefile.in
@@ -0,0 +1,250 @@
+# Makefile.in generated automatically by automake 1.1n from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = true
+PRE_INSTALL = true
+POST_INSTALL = true
+NORMAL_UNINSTALL = true
+PRE_UNINSTALL = true
+POST_UNINSTALL = true
+CC = @CC@
+LEX = @LEX@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+
+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
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+dc_OBJECTS = dc.o misc.o eval.o stack.o array.o numeric.o string.o
+dc_LDADD = $(LDADD)
+dc_DEPENDENCIES = ../lib/libbc.a
+dc_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(LDFLAGS) -o $@
+HEADERS = $(noinst_HEADERS)
+
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+SOURCES = $(dc_SOURCES)
+OBJECTS = $(dc_OBJECTS)
+
+default: all
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu dc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`"; \
+ $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ $(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ rm -f *.o core
+
+clean-compile:
+
+distclean-compile:
+ rm -f *.tab.c
+
+maintainer-clean-compile:
+
+dc: $(dc_OBJECTS) $(dc_DEPENDENCIES)
+ @rm -f dc
+ $(LINK) $(dc_LDFLAGS) $(dc_OBJECTS) $(dc_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES)
+ here=`pwd` && cd $(srcdir) && mkid -f$$here/ID $(SOURCES) $(HEADERS)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ done; \
+ test -z "$(ETAGS_ARGS)$(SOURCES)$(HEADERS)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $(SOURCES) $(HEADERS) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = dc
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done
+info:
+dvi:
+check: all
+ $(MAKE)
+installcheck:
+install-exec: install-binPROGRAMS
+ @$(NORMAL_INSTALL)
+
+install-data:
+ @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+ @:
+
+uninstall: uninstall-binPROGRAMS
+
+all: $(PROGRAMS) $(HEADERS) Makefile
+
+install-strip:
+ $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
+installdirs:
+ $(mkinstalldirs) $(bindir)
+
+
+mostlyclean-generic:
+ test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ rm -f Makefile $(DISTCLEANFILES)
+ rm -f config.cache config.log stamp-h
+ test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+ test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-tags mostlyclean-generic
+
+clean: clean-binPROGRAMS clean-compile clean-tags clean-generic \
+ mostlyclean
+
+distclean: distclean-binPROGRAMS distclean-compile distclean-tags \
+ distclean-generic clean
+ rm -f config.status
+
+maintainer-clean: maintainer-clean-binPROGRAMS maintainer-clean-compile \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: default mostlyclean-binPROGRAMS distclean-binPROGRAMS \
+clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \
+install-binPROGRAMS mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info dvi installcheck \
+install-exec install-data install uninstall all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+$(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/contrib/bc/dc/array.c b/contrib/bc/dc/array.c
new file mode 100644
index 000000000000..2fc1b7e524bf
--- /dev/null
+++ b/contrib/bc/dc/array.c
@@ -0,0 +1,108 @@
+/*
+ * implement arrays for dc
+ *
+ * Copyright (C) 1994 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.; 675 Mass Ave. Cambridge, MA 02139, 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;
+};
+typedef struct dc_array dc_array;
+
+/* I can find no reason not to place arrays in their own namespace... */
+static dc_array *dc_array_register[DC_REGCOUNT];
+
+
+/* initialize the arrays to their initial values */
+void
+dc_array_init DC_DECLVOID()
+{
+ int i;
+
+ for (i=0; i<DC_REGCOUNT; ++i)
+ dc_array_register[i] = NULL;
+}
+
+/* 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
+{
+ dc_array *cur;
+ dc_array *prev=NULL;
+ dc_array *newentry;
+
+ array_id = regmap(array_id);
+ cur = dc_array_register[array_id];
+ while (cur && cur->Index < Index){
+ prev = cur;
+ cur = cur->next;
+ }
+ if (cur && 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{
+ newentry = dc_malloc(sizeof *newentry);
+ newentry->Index = Index;
+ newentry->value = value;
+ newentry->next = cur;
+ if (prev)
+ prev->next = newentry;
+ else
+ dc_array_register[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
+{
+ dc_array *cur;
+
+ for (cur=dc_array_register[regmap(array_id)]; cur; cur=cur->next)
+ if (cur->Index == Index)
+ return dc_dup(cur->value);
+ return dc_int2data(0);
+}
diff --git a/contrib/bc/dc/dc-proto.h b/contrib/bc/dc/dc-proto.h
new file mode 100644
index 000000000000..5aa9bc79e90a
--- /dev/null
+++ b/contrib/bc/dc/dc-proto.h
@@ -0,0 +1,83 @@
+/*
+ * prototypes of all externally visible dc functions
+ *
+ * Copyright (C) 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, 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.; 675 Mass Ave. Cambridge, MA 02139, 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 void dc_array_set DC_PROTO((int, int, dc_data));
+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_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_boolean, dc_boolean));
+extern void dc_out_str DC_PROTO((dc_str, dc_boolean, dc_boolean));
+extern void dc_print DC_PROTO((dc_data, int));
+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_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_boolean));
+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_boolean));
+extern int dc_tell_scale DC_PROTO((dc_num, dc_boolean));
+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/contrib/bc/dc/dc-regdef.h b/contrib/bc/dc/dc-regdef.h
new file mode 100644
index 000000000000..129d0ae6596c
--- /dev/null
+++ b/contrib/bc/dc/dc-regdef.h
@@ -0,0 +1,40 @@
+/*
+ * definitions for dc's "register" declarations
+ *
+ * Copyright (C) 1994 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.; 675 Mass Ave. Cambridge, MA 02139, USA.
+ */
+
+#ifdef HAVE_LIMITS_H
+# include <limits.h> /* UCHAR_MAX */
+#endif
+
+/* determine how many register stacks there are */
+#ifndef DC_REGCOUNT
+# ifndef UCHAR_MAX
+# define DC_REGCOUNT 256
+# else
+# define DC_REGCOUNT (UCHAR_MAX+1)
+# endif
+#endif /* not DC_REGCOUNT */
+
+/* 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/contrib/bc/dc/dc.c b/contrib/bc/dc/dc.c
new file mode 100644
index 000000000000..85da40f32558
--- /dev/null
+++ b/contrib/bc/dc/dc.c
@@ -0,0 +1,173 @@
+/*
+ * implement the "dc" Desk Calculator language.
+ *
+ * Copyright (C) 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, 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.; 675 Mass Ave. Cambridge, MA 02139, 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
+#include <getopt.h>
+#include "dc.h"
+#include "dc-proto.h"
+
+#include "version.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 */
+
+/* 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\
+Report bugs to @\n\
+", progname);
+}
+
+static void
+show_version DC_DECLVOID()
+{
+ printf("%s\n\n", DC_VERSION);
+ printf("Email bug reports to: bug-gnu-utils@prep.ai.mit.edu .\n");
+ printf("Be sure to include the word ``dc'' \
+somewhere in the ``Subject:'' field.\n");
+}
+
+/* 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)
+ return s;
+ return p + 1;
+}
+
+static void
+try_file(const char *filename) {
+ FILE *input;
+
+ if ( !(input=fopen(filename, "r")) ) {
+ fprintf(stderr, "Could not open file ");
+ perror(filename);
+ exit(EXIT_FAILURE);
+ }
+ if (dc_evalfile(input))
+ exit(EXIT_FAILURE);
+ fclose(input);
+}
+
+
+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, '/');
+ dc_math_init();
+ dc_string_init();
+ dc_register_init();
+ dc_array_init();
+
+ while ((c = getopt_long(argc, argv, "hVe:", long_opts, (int *)0)) != EOF) {
+ switch (c) {
+ case 'e':
+ { dc_data string = dc_makestring(optarg, strlen(optarg));
+ if (dc_evalstr(string))
+ return EXIT_SUCCESS;
+ dc_free_str(&string.v.string);
+ did_eval = 1;
+ }
+ break;
+ case 'f':
+ try_file(optarg);
+ did_eval = 1;
+ break;
+ case 'h':
+ usage(stdout);
+ return EXIT_SUCCESS;
+ case 'V':
+ show_version();
+ return EXIT_SUCCESS;
+ default:
+ usage(stderr);
+ return EXIT_FAILURE;
+ }
+ }
+
+ for (; optind < argc; ++optind) {
+ if (strcmp(argv[optind], "-") == 0) {
+ if (dc_evalfile(stdin))
+ return EXIT_FAILURE;
+ } else {
+ try_file(argv[optind]);
+ }
+ did_eval = 1;
+ }
+ if (!did_eval) {
+ /* if no -e commands and no command files, then eval stdin */
+ if (dc_evalfile(stdin))
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/bc/dc/dc.h b/contrib/bc/dc/dc.h
new file mode 100644
index 000000000000..eeac77b29e2e
--- /dev/null
+++ b/contrib/bc/dc/dc.h
@@ -0,0 +1,78 @@
+/*
+ * Header file for dc routines
+ *
+ * Copyright (C) 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, 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.; 675 Mass Ave. Cambridge, MA 02139, 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_FALSE, DC_TRUE} dc_boolean;
+
+
+/* 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/contrib/bc/dc/eval.c b/contrib/bc/dc/eval.c
new file mode 100644
index 000000000000..cac4cb1142a7
--- /dev/null
+++ b/contrib/bc/dc/eval.c
@@ -0,0 +1,646 @@
+/*
+ * evaluate the dc language, from a FILE* or a string
+ *
+ * Copyright (C) 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, 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.; 675 Mass Ave. Cambridge, MA 02139, 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 "dc.h"
+#include "dc-proto.h"
+
+typedef enum {
+ DC_OKAY = DC_SUCCESS, /* no further intervention needed for this command */
+ DC_EATONE, /* caller needs to eat the lookahead char */
+ DC_QUIT, /* quit out of unwind_depth levels of evaluation */
+
+ /* with the following return values, the caller does not have to
+ * fret about stdin_lookahead's value
+ */
+ 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_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;
+
+/* 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;
+
+
+/* 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)
+ return EOF;
+ return *input_str_string++;
+}
+
+
+
+/* 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;
+}
+
+
+/* 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
+ */
+static dc_status
+dc_func DC_DECLARG((c, peekc))
+ int c DC_DECLSEP
+ int peekc DC_DECLEND
+{
+ /* we occasionally need these for temporary data */
+ /* Despite the GNU coding standards, it is much easier
+ * to have these declared once here, since this function
+ * is just one big switch statement.
+ */
+ 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 and exp must be a
+ * non-negative integer. 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)
+ if (dc_register_get(peekc, &datum) == DC_SUCCESS)
+ if (dc_eval_and_free_str(datum) == DC_QUIT)
+ return DC_QUIT;
+ 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)
+ if (dc_register_get(peekc, &datum) == DC_SUCCESS)
+ if (dc_eval_and_free_str(datum) == DC_QUIT)
+ return DC_QUIT;
+ 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)
+ if (dc_register_get(peekc, &datum) == DC_SUCCESS)
+ if (dc_eval_and_free_str(datum) == DC_QUIT)
+ return DC_QUIT;
+ return DC_EATONE;
+ case '?': /* read a line from standard-input and eval it */
+ if (stdin_lookahead != EOF){
+ ungetc(stdin_lookahead, stdin);
+ stdin_lookahead = EOF;
+ }
+ if (dc_eval_and_free_str(dc_readstring(stdin, '\n', '\n')) == DC_QUIT)
+ return DC_QUIT;
+ return DC_OKAY;
+ case '[': /* read to balancing ']' into a dc_str */
+ return DC_STR;
+ case '!': /* read to newline and call system() on resulting string */
+ 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_TRUE);
+ dc_free_num(&datum.v.number);
+ }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_TRUE);
+ if ( ! (2 <= tmpint && tmpint <= DC_IBASE_MAX) )
+ fprintf(stderr,
+ "%s: input base must be a number \
+between 2 and %d (inclusive)\n",
+ progname, DC_IBASE_MAX);
+ else
+ dc_ibase = tmpint;
+ }
+ 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_TRUE);
+ 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 '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_TRUE);
+ 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 */
+ if (dc_top_of_stack(&datum) == DC_SUCCESS)
+ dc_print(datum, dc_obase);
+ break;
+ case 'q': /* quit two levels of evaluation, posibly exiting program */
+ unwind_depth = 2;
+ 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 */
+ if (dc_pop(&datum) == DC_SUCCESS){
+ if (datum.dc_type == DC_STRING){
+ if (dc_eval_and_free_str(datum) == DC_QUIT)
+ return DC_QUIT;
+ }else if (datum.dc_type == DC_NUMBER){
+ dc_push(datum);
+ }else{
+ dc_garbage("at top of stack", -1);
+ }
+ }
+ break;
+ 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': /* print the value popped off of top-of-stack;
+ * do not add a trailing newline
+ */
+ if (dc_pop(&datum) == DC_SUCCESS){
+ if (datum.dc_type == DC_STRING)
+ dc_out_str(datum.v.string, DC_FALSE, DC_TRUE);
+ else if (datum.dc_type == DC_NUMBER)
+ dc_out_num(datum.v.number, dc_obase, DC_FALSE, DC_TRUE);
+ 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_TRUE);
+ if (unwind_depth > 0)
+ return DC_QUIT;
+ 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_TRUE);
+ 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_TRUE);
+ 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_TRUE)));
+ 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_TRUE);
+ 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_TRUE);
+ 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;
+}
+
+
+/* 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;
+
+ if (string.dc_type != DC_STRING){
+ fprintf(stderr,
+ "%s: eval called with non-string argument\n",
+ progname);
+ return DC_OKAY;
+ }
+ s = dc_str2charp(string.v.string);
+ end = s + dc_strlen(string.v.string);
+ while (s < end){
+ c = *(const unsigned char *)s++;
+ peekc = EOF;
+ if (s < end)
+ peekc = *(const unsigned char *)s;
+ switch (dc_func(c, peekc)){
+ case DC_OKAY:
+ break;
+ case DC_EATONE:
+ if (peekc != EOF)
+ ++s;
+ break;
+ case DC_QUIT:
+ if (unwind_depth > 0){
+ --unwind_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 = p - s;
+ dc_push(dc_makestring(s, len-1));
+ s = p;
+ break;
+ case DC_SYSTEM:
+ s = dc_system(s);
+ case DC_COMMENT:
+ s = memchr(s, '\n', (size_t)(end-s));
+ if (!s)
+ s = end;
+ else
+ ++s;
+ break;
+
+ case DC_EOF_ERROR:
+ fprintf(stderr, "%s: unexpected EOS\n", progname);
+ return DC_OKAY;
+ }
+ }
+ return DC_OKAY;
+}
+
+
+/* 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;
+ dc_data datum;
+
+ 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;
+ switch (dc_func(c, peekc)){
+ case DC_OKAY:
+ if (stdin_lookahead != peekc && fp == stdin)
+ peekc = getc(fp);
+ break;
+ case DC_EATONE:
+ peekc = getc(fp);
+ break;
+ case DC_QUIT:
+ if (unwind_noexit != DC_TRUE)
+ return DC_FAIL;
+ 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));
+ break;
+ case DC_STR:
+ ungetc(peekc, fp);
+ datum = dc_readstring(fp, '[', ']');
+ dc_push(datum);
+ peekc = getc(fp);
+ break;
+ case DC_SYSTEM:
+ ungetc(peekc, fp);
+ datum = dc_readstring(stdin, '\n', '\n');
+ (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_EOF_ERROR:
+ fprintf(stderr, "%s: unexpected EOF\n", progname);
+ return DC_FAIL;
+ }
+ }
+ return DC_SUCCESS;
+}
diff --git a/contrib/bc/dc/misc.c b/contrib/bc/dc/misc.c
new file mode 100644
index 000000000000..8c360cacb055
--- /dev/null
+++ b/contrib/bc/dc/misc.c
@@ -0,0 +1,177 @@
+/*
+ * misc. functions for the "dc" Desk Calculator language.
+ *
+ * Copyright (C) 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, 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.; 675 Mass Ave. Cambridge, MA 02139, USA.
+ */
+
+/* This module contains miscelaneous functions that have no
+ * special knowledge of any private data structures.
+ * They could all be moved to their own separate modules, but
+ * are agglomerated here for 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"
+
+#include "version.h"
+
+#ifndef EXIT_FAILURE /* C89 <stdlib.h> */
+# define EXIT_FAILURE 1
+#endif
+
+
+/* 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)
+ dc_memfail();
+ return result;
+}
+
+
+/* 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", id, id, suffix);
+ else
+ fprintf(fp, "%#o%s", id, suffix);
+}
+
+
+/* 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();
+}
+
+
+/* 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) {
+ len = 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);
+}
+
+
+/* print out the indicated value */
+void
+dc_print DC_DECLARG((value, obase))
+ dc_data value DC_DECLSEP
+ int obase DC_DECLEND
+{
+ if (value.dc_type == DC_NUMBER) {
+ dc_out_num(value.v.number, obase, DC_TRUE, DC_FALSE);
+ } else if (value.dc_type == DC_STRING) {
+ dc_out_str(value.v.string, DC_TRUE, DC_FALSE);
+ } 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);
+}
diff --git a/contrib/bc/dc/numeric.c b/contrib/bc/dc/numeric.c
new file mode 100644
index 000000000000..ec1934427dfc
--- /dev/null
+++ b/contrib/bc/dc/numeric.c
@@ -0,0 +1,536 @@
+/*
+ * interface dc to the bc numeric routines
+ *
+ * Copyright (C) 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, 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.; 675 Mass Ave. Cambridge, MA 02139, 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.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include "bcdefs.h"
+#include "proto.h"
+#include "global.h"
+#include "dc.h"
+#include "dc-proto.h"
+
+/* 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 */
+#define CastNum(x) ((bc_num)(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 DC_DECLSEP
+ dc_num *result DC_DECLEND
+{
+ init_num((bc_num *)result);
+ bc_add(CastNum(a), CastNum(b), (bc_num *)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 DC_DECLSEP
+ dc_num *result DC_DECLEND
+{
+ init_num((bc_num *)result);
+ bc_sub(CastNum(a), CastNum(b), (bc_num *)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
+{
+ init_num((bc_num *)result);
+ bc_multiply(CastNum(a), CastNum(b), (bc_num *)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
+{
+ init_num((bc_num *)result);
+ if (bc_divide(CastNum(a), CastNum(b), (bc_num *)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
+{
+ init_num((bc_num *)quotient);
+ init_num((bc_num *)remainder);
+ if (bc_divmod(CastNum(a), CastNum(b),
+ (bc_num *)quotient, (bc_num *)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
+{
+ init_num((bc_num *)result);
+ if (bc_modulo(CastNum(a), CastNum(b), (bc_num *)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
+{
+ init_num((bc_num *)result);
+ if (bc_raisemod(CastNum(base), CastNum(expo), CastNum(mod),
+ (bc_num *)result, kscale)){
+ if (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
+{
+ init_num((bc_num *)result);
+ bc_raise(CastNum(a), CastNum(b), (bc_num *)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 = copy_num(CastNum(value));
+ if (!bc_sqrt(&tmp, kscale)){
+ fprintf(stderr, "%s: square root of negative number\n", progname);
+ free_num(&tmp);
+ return DC_DOMAIN_ERROR;
+ }
+ *((bc_num *)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));
+}
+
+/* attempt to convert a dc_num to its corresponding int value
+ * If discard_flag is true then deallocate the value after use.
+ */
+int
+dc_num2int DC_DECLARG((value, discard_flag))
+ dc_num value DC_DECLSEP
+ dc_boolean discard_flag DC_DECLEND
+{
+ long result;
+
+ result = num2long(CastNum(value));
+ if (discard_flag)
+ 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;
+
+ init_num((bc_num *)&result.v.number);
+ int2num((bc_num *)&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;
+
+ init_num(&tmp);
+ init_num(&build);
+ init_num(&base);
+ result = copy_num(_zero_);
+ 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)();
+ int2num(&tmp, digit);
+ bc_multiply(result, base, &result, 0);
+ bc_add(result, tmp, &result, 0);
+ }
+ if (c == '.'){
+ free_num(&build);
+ free_num(&tmp);
+ divisor = copy_num(_one_);
+ build = 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;
+ 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);
+
+ free_num(&tmp);
+ free_num(&build);
+ free_num(&base);
+ if (readahead)
+ *readahead = c;
+ full_result.v.number = (dc_num)result;
+ full_result.dc_type = DC_NUMBER;
+ return full_result;
+}
+
+
+/* return the "length" of the number */
+int
+dc_numlen DC_DECLARG((value))
+ dc_num value DC_DECLEND
+{
+ bc_num num = CastNum(value);
+
+ /* is this right??? */
+ return num->n_len + num->n_scale;
+}
+
+/* return the scale factor of the passed dc_num
+ * If discard_flag is true then deallocate the value after use.
+ */
+int
+dc_tell_scale DC_DECLARG((value, discard_flag))
+ dc_num value DC_DECLSEP
+ dc_boolean discard_flag DC_DECLEND
+{
+ int kscale;
+
+ kscale = CastNum(value)->n_scale;
+ if (discard_flag)
+ dc_free_num(&value);
+ return kscale;
+}
+
+
+/* initialize the math subsystem */
+void
+dc_math_init DC_DECLVOID()
+{
+ init_numbers();
+}
+
+/* print out a dc_num in output base obase to stdout;
+ * if newline is true, terminate output with a '\n';
+ * if discard_flag is true then deallocate the value after use
+ */
+void
+dc_out_num DC_DECLARG((value, obase, newline, discard_flag))
+ dc_num value DC_DECLSEP
+ int obase DC_DECLSEP
+ dc_boolean newline DC_DECLSEP
+ dc_boolean discard_flag DC_DECLEND
+{
+ out_num(CastNum(value), obase, out_char);
+ if (newline)
+ out_char('\n');
+ if (discard_flag)
+ dc_free_num(&value);
+}
+
+
+/* deallocate an instance of a dc_num */
+void
+dc_free_num DC_DECLARG((value))
+ dc_num *value DC_DECLEND
+{
+ free_num((bc_num *)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;
+}
+
+
+
+/*---------------------------------------------------------------------------\
+| 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_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#ifdef HAVE_STDARG_H
+# include <stdarg.h>
+#else
+# include <varargs.h>
+#endif
+
+
+int out_col = 0;
+
+/* 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>". */
+
+void
+out_char (ch)
+ char ch;
+{
+
+ if (ch == '\n')
+ {
+ out_col = 0;
+ putchar ('\n');
+ }
+ else
+ {
+ out_col++;
+ if (out_col == 70)
+ {
+ 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;
+ char error_mesg [255];
+
+#ifdef HAVE_STDARG_H
+ 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. */
+
+#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;
+ char error_mesg [255];
+
+#ifdef HAVE_STDARG_H
+ 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);
+}
diff --git a/contrib/bc/dc/stack.c b/contrib/bc/dc/stack.c
new file mode 100644
index 000000000000..c8cd195af351
--- /dev/null
+++ b/contrib/bc/dc/stack.c
@@ -0,0 +1,457 @@
+/*
+ * implement stack functions for dc
+ *
+ * Copyright (C) 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, 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.; 675 Mass Ave. Cambridge, MA 02139, 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 implementaion suffices: */
+struct dc_list {
+ dc_data value;
+ struct dc_list *link;
+};
+typedef struct dc_list dc_list;
+
+/* the anonymous evaluation stack */
+static dc_list *dc_stack=NULL;
+
+/* the named register stacks */
+static dc_list *dc_register[DC_REGCOUNT];
+
+
+/* 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->link = NULL;
+ return result;
+}
+
+
+/* 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 || !dc_stack->link){
+ 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 || !dc_stack->link){
+ 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 || !dc_stack->link){
+ 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 || !dc_stack->link || !dc_stack->link->link){
+ 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);
+ }
+}
+
+
+/* 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; 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);
+ 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){
+ 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 ){
+ 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 )
+ 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
+ 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){
+ 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;
+ 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){
+ 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;
+ free(r);
+ return DC_SUCCESS;
+}
+
+
+/* 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; n=n->link)
+ ++depth;
+ return depth;
+}
+
+
+/* return the length of the indicated data value;
+ * if discard_flag is true, 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_flag))
+ dc_data value DC_DECLSEP
+ dc_boolean discard_flag DC_DECLEND
+{
+ int length;
+
+ if (value.dc_type == DC_NUMBER){
+ length = dc_numlen(value.v.number);
+ if (discard_flag == DC_TRUE)
+ dc_free_num(&value.v.number);
+ } else if (value.dc_type == DC_STRING) {
+ length = dc_strlen(value.v.string);
+ if (discard_flag == DC_TRUE)
+ dc_free_str(&value.v.string);
+ } else {
+ dc_garbage("in tell_length", -1);
+ /*NOTREACHED*/
+ length = 0; /*just to suppress spurious compiler warnings*/
+ }
+ return length;
+}
+
+
+
+/* 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; n=n->link)
+ dc_print(n->value, obase);
+}
diff --git a/contrib/bc/dc/string.c b/contrib/bc/dc/string.c
new file mode 100644
index 000000000000..35bc2630532d
--- /dev/null
+++ b/contrib/bc/dc/string.c
@@ -0,0 +1,208 @@
+/*
+ * implement string functions for dc
+ *
+ * Copyright (C) 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, 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.; 675 Mass Ave. Cambridge, MA 02139, 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 */
+};
+
+
+/* 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_boolean newline DC_DECLSEP
+ dc_boolean discard_flag DC_DECLEND
+{
+ fwrite(value->s_ptr, value->s_len, sizeof *value->s_ptr, stdout);
+ if (newline == DC_TRUE)
+ printf("\n");
+ if (discard_flag == DC_TRUE)
+ 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){
+ /* initial buflen should be large enough to handle most cases */
+ buflen = 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)
+ 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;
+}
+
+
+/* initialize the strings subsystem */
+void
+dc_string_init DC_DECLVOID()
+{
+ /* nothing to do for this implementation */
+}
diff --git a/contrib/bc/doc/Makefile.am b/contrib/bc/doc/Makefile.am
new file mode 100644
index 000000000000..d4ed7ebdcc88
--- /dev/null
+++ b/contrib/bc/doc/Makefile.am
@@ -0,0 +1,10 @@
+## Process this file with automake to produce Makefile.in
+
+info_TEXINFOS = dc.texi
+MAKEINFO = makeinfo --no-split
+
+# FIXME: remove this when automake has been fixed to include these
+# files automatically
+EXTRA_DIST = bc.1 dc.1
+
+man_MANS = bc.1 dc.1
diff --git a/contrib/bc/doc/Makefile.in b/contrib/bc/doc/Makefile.in
new file mode 100644
index 000000000000..770e20145386
--- /dev/null
+++ b/contrib/bc/doc/Makefile.in
@@ -0,0 +1,280 @@
+# Makefile.in generated automatically by automake 1.1n from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = true
+PRE_INSTALL = true
+POST_INSTALL = true
+NORMAL_UNINSTALL = true
+PRE_UNINSTALL = true
+POST_UNINSTALL = true
+CC = @CC@
+LEX = @LEX@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+YACC = @YACC@
+
+info_TEXINFOS = dc.texi
+MAKEINFO = makeinfo --no-split
+
+# FIXME: remove this when automake has been fixed to include these
+# files automatically
+EXTRA_DIST = bc.1 dc.1
+
+man_MANS = bc.1 dc.1
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+TEXI2DVI = texi2dvi
+TEXINFO_TEX = $(srcdir)/texinfo.tex
+INFO_DEPS = dc.info
+DVIS = dc.dvi
+TEXINFOS = dc.texi
+MANS = bc.1 dc.1
+
+NROFF = nroff
+DIST_COMMON = Makefile.am Makefile.in texinfo.tex
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+default: all
+
+.SUFFIXES:
+.SUFFIXES: .texi .texinfo .info .dvi .ps
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+dc.info: dc.texi
+dc.dvi: dc.texi
+
+
+DVIPS = dvips
+
+.texi.info:
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texi.dvi:
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+
+.texi:
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo.info:
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo:
+ cd $(srcdir) \
+ && $(MAKEINFO) `echo $< | sed 's,.*/,,'`
+
+.texinfo.dvi:
+ TEXINPUTS=$(srcdir):$$TEXINPUTS \
+ MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
+.dvi.ps:
+ $(DVIPS) $< -o $@
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(infodir)
+ @for file in $(INFO_DEPS); do \
+ d=$(srcdir); \
+ for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9]`; do \
+ if test -f $$d/$$ifile; then \
+ echo " $(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile"; \
+ $(INSTALL_DATA) $$d/$$ifile $(infodir)/$$ifile; \
+ else : ; fi; \
+ done; \
+ done
+ @$(POST_INSTALL)
+ @if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
+ for file in $(INFO_DEPS); do \
+ echo " install-info --info-dir=$(infodir) $(infodir)/$$file";\
+ install-info --info-dir=$(infodir) $(infodir)/$$file; :;\
+ done; \
+ else : ; fi
+
+uninstall-info:
+ $(PRE_UNINSTALL)
+ if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
+ ii=yes; \
+ else ii=; fi; \
+ for file in $(INFO_DEPS); do \
+ test -z $ii || install-info --info-dir=$(infodir) --remove $$file; \
+ done
+ $(NORMAL_UNINSTALL)
+ for file in $(INFO_DEPS); do \
+ (cd $(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9]); \
+ done
+
+dist-info: $(INFO_DEPS)
+ for base in $(INFO_DEPS); do \
+ d=$(srcdir); \
+ for file in `cd $$d && eval echo $$base*`; do \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done; \
+ done
+
+mostlyclean-info:
+ rm -f dc.aux dc.cp dc.cps dc.dvi dc.fn dc.fns dc.ky dc.log dc.pg dc.toc \
+ dc.tp dc.tps dc.vr dc.vrs dc.op dc.tr dc.cv
+
+clean-info:
+
+distclean-info:
+
+maintainer-clean-info:
+ for i in $(INFO_DEPS); do rm -f `eval echo $$i*`; done
+install-man: $(MANS)
+ $(NORMAL_INSTALL)
+ $(mkinstalldirs) $(mandir)/man1
+ @sect=1; \
+ inst=`echo "bc" | sed '$(transform)'`.1; \
+ if test -f $(srcdir)/bc.1; then file=$(srcdir)/bc.1; \
+ else file=bc.1; fi; \
+ echo " $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst"; \
+ $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst
+ @sect=1; \
+ inst=`echo "dc" | sed '$(transform)'`.1; \
+ if test -f $(srcdir)/dc.1; then file=$(srcdir)/dc.1; \
+ else file=dc.1; fi; \
+ echo " $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst"; \
+ $(INSTALL_DATA) $$file $(mandir)/man$$sect/$$inst
+
+uninstall-man:
+ $(NORMAL_UNINSTALL)
+ inst=`echo "bc" | sed '$(transform)'`.1; \
+ rm -f $(mandir)/man1/$$inst
+ inst=`echo "dc" | sed '$(transform)'`.1; \
+ rm -f $(mandir)/man1/$$inst
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = doc
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done
+ $(MAKE) distdir="$(distdir)" dist-info
+info: $(INFO_DEPS)
+dvi: $(DVIS)
+check: all
+ $(MAKE)
+installcheck:
+install-exec:
+ @$(NORMAL_INSTALL)
+
+install-data: install-info-am install-man
+ @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+ @:
+
+uninstall: uninstall-info uninstall-man
+
+all: $(INFO_DEPS) $(MANS) Makefile
+
+install-strip:
+ $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
+installdirs:
+ $(mkinstalldirs) $(infodir) $(mandir)/man1
+
+
+mostlyclean-generic:
+ test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+ test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ rm -f Makefile $(DISTCLEANFILES)
+ rm -f config.cache config.log stamp-h
+ test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+ test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean: mostlyclean-info mostlyclean-generic
+
+clean: clean-info clean-generic mostlyclean
+
+distclean: distclean-info distclean-generic clean
+ rm -f config.status
+
+maintainer-clean: maintainer-clean-info maintainer-clean-generic \
+ distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: default install-info-am uninstall-info mostlyclean-info \
+distclean-info clean-info maintainer-clean-info install-man \
+uninstall-man tags distdir info dvi installcheck install-exec \
+install-data install uninstall all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# 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/contrib/bc/doc/bc.1 b/contrib/bc/doc/bc.1
new file mode 100644
index 000000000000..e0cef9cff86f
--- /dev/null
+++ b/contrib/bc/doc/bc.1
@@ -0,0 +1,787 @@
+.\"
+.\" bc.1 - the *roff document processor source for the bc manual
+.\"
+.\" 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+.\"
+.\" You may contact the author by:
+.\" e-mail: phil@cs.wwu.edu
+.\" us-mail: Philip A. Nelson
+.\" Computer Science Department, 9062
+.\" Western Washington University
+.\" Bellingham, WA 98226-9062
+.\"
+.\"
+.TH bc 1 .\" "Command Manual" v1.04 "June 22, 1995"
+.SH NAME
+bc - An arbitrary precision calculator language
+.SH SYNTAX
+\fBbc\fR [ \fB-lwsqv\fR ] [long-options] [ \fI file ...\fR ]
+.SH VERSION
+This man page documents GNU bc version 1.04.
+.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 -l
+Define the standard math library.
+.IP -w
+Give warnings for extensions to POSIX \fBbc\fR.
+.IP -s
+Process exactly the POSIX \fBbc\fR language.
+.IP -q
+Do not print the normal GNU bc welcome.
+.IP -v
+Print the version number and copyright and quit.
+.IP --mathlib
+Define the standard math library.
+.IP --warn
+Give warnings for extensions to POSIX \fBbc\fR.
+.IP --standard
+Process exactly the POSIX \fBbc\fR language.
+.IP --quiet
+Do not print the normal GNU bc welcome.
+.IP --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 cause the side effect of assigning the printed value the 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 the 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.)
+.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. Numbers are only call by value parameters. Arrays are only
+call by variable. 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 variable 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
+in the fact that 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.
+.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 OPTION
+GNU \fBbc\fR can be compiled (via a configure option) to use the
+GNU \fBreadline\fR input editor library. This allows the user
+to do more 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. A value of -1 means that an unlimited number
+of history lines are retained. This is the default value.
+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. For more information, read the
+user manuals for the GNU \fBreadline\fR and \fBhistory\fR libraries.
+.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 "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 "=+, =-, =*, =/, =%, =^"
+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 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.
+.IP "code size"
+Each function and the "main" program are limited to 16384 bytes of
+compiled byte code each. This limit (BC_MAX_SEGS) can be easily changed
+to have more than 16 segments of 1024 bytes.
+.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 environent 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 specifing the number of characters in an
+output line for numbers. This includes the backslash and newline characters
+for long numbers.
+.SH FILES
+In most installations, \fBbc\fR is completely self-contained.
+Where executable size is of importance or the C compiler does
+not deal with very long strings, \fBbc\fR will read
+the standard math library from the file /usr/local/lib/libmath.b.
+(The actual location may vary. It may be /lib/libmath.b.)
+.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-gnu-utils@prep.ai.mit.edu .
+Be sure to include the word ``bc'' somewhere in the ``Subject:'' field.
+.SH AUTHOR
+.nf
+Philip A. Nelson
+phil@cs.wwu.edu
+.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/contrib/bc/doc/dc.1 b/contrib/bc/doc/dc.1
new file mode 100644
index 000000000000..f64e0f91a815
--- /dev/null
+++ b/contrib/bc/doc/dc.1
@@ -0,0 +1,436 @@
+.\"
+.\" dc.1 - the *roff document processor source for the dc manual
+.\"
+.\" This file is part of GNU dc.
+.\" Copyright (C) 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, 675 Mass Ave, Cambridge, MA 02139, USA.
+.\"
+.TH DC 1 "1997-03-25" "GNU Project"
+.ds dc \fIdc\fP
+.ds Dc \fIDc\fP
+.SH NAME
+dc \- an arbitrary precision calculator
+.SH SYNOPSIS
+dc
+.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 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.
+.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 P
+Prints the value on the top of the stack, popping it off,
+and does not print a newline after.
+.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 is controlled
+by the current precision value (see below) and does not
+depend on the values being multiplied.
+.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 division is done with as many fraction digits
+as the precision value specifies,
+and the remainder is also computed with that many fraction digits.
+.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.
+The precision value specifies the number of fraction
+digits in the result.
+For small numbers this is like the sequence \fBSm lble^ Lm%\fP,
+but, unlike \fB^\fP, this command will work with arbritrarily 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.
+.PP
+The remainder operation
+.B %
+requires some explanation:
+applied to arguments ``a'' and ``b'' it produces ``a - (b * (a / b))'',
+where ``a / b'' is computed in the current precision.
+.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.
+.SH
+Registers
+.PP
+\*(Dc provides 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 36 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 can 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 less.
+.TP
+.BI = r
+Similar but invokes the macro if the two numbers popped are 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.
+.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.
+.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.
+.SH
+NOTES
+.PP
+The array operations
+.B :
+and
+.B ;
+are usually only used by traditional implementations of
+.IR bc .
+(The GNU
+.I bc
+is self contained and does not need \*(dc to run.)
+.SH
+BUGS
+.PP
+Email bug reports to
+.BR bug-gnu-utils@prep.ai.mit.edu .
+Be sure to include the word ``dc'' somewhere in the ``Subject:'' field.
diff --git a/contrib/bc/doc/dc.texi b/contrib/bc/doc/dc.texi
new file mode 100644
index 000000000000..e0ade802b1cc
--- /dev/null
+++ b/contrib/bc/doc/dc.texi
@@ -0,0 +1,497 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename dc.info
+@settitle dc, an arbitrary precision calculator
+@c %**end of header
+
+@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
+This file documents @sc{dc}, an arbitrary precision calculator.
+
+Published by the Free Software Foundation,
+675 Massachusetts Avenue,
+Cambridge, MA 02139 USA
+
+Copyright (C) 1984 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
+
+@author by Ken Pizzini
+@author original manual by Richard Stallman
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1994, 1997 Free Software Foundation, Inc.
+
+@sp 2
+Published by the Free Software Foundation, @*
+675 Massachusetts Avenue, @*
+Cambridge, MA 02139 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
+@page
+
+@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
+* Notes:: Notes
+@end menu
+
+@node Introduction, Invocation, Top, Top
+@comment node-name, next, previous, up
+@chapter Introduction
+
+@sc{dc} is a reverse-polish desk calculator
+which supports unlimited precision arithmetic.
+It also allows you to define and call macros.
+Normally @sc{dc} reads from the standard input;
+if any command arguments are given to it, they are filenames,
+and @sc{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} does not exit;
+it is used to abort macros that are looping, etc.
+(Currently this is not true; @kbd{C-c} does exit.)
+
+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 @sc{dc}, type the digits,
+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
+
+@sc{dc} may be invoked with the following command-line options:
+@table @samp
+
+@item -e @var{expr}
+@item --expression=@var{expr}
+Evaluate @var{expr} as @sc{dc} commands.
+
+@item -f @var{file}
+@item --file=@var{file}
+Read and evaluate @sc{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 P
+Prints the value on the top of the stack, popping it off,
+and does not print a newline after.
+
+@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
+
+@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 controlled
+by the current precision value (see below) and does not
+depend on the values being multiplied.
+
+@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 division is done with as many fraction digits
+as the precision value specifies,
+and the remainder is also computed with that many fraction digits.
+
+@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 mo