summaryrefslogtreecommitdiffstats
path: root/gnu
diff options
context:
space:
mode:
authorandreas <andreas@FreeBSD.org>1998-04-29 22:05:39 +0000
committerandreas <andreas@FreeBSD.org>1998-04-29 22:05:39 +0000
commite2ae216f29b9ae75400cfd048d6afa489eef800e (patch)
tree78e08017103fb744dd43354cae40a479c74f0235 /gnu
parent854c44e14abd0402ff34e22a4f758647e5e1def6 (diff)
downloadFreeBSD-src-e2ae216f29b9ae75400cfd048d6afa489eef800e.zip
FreeBSD-src-e2ae216f29b9ae75400cfd048d6afa489eef800e.tar.gz
remove old bc-1.0.3 stuff
modify Makefile, to get bc-1.0.4 from src/contrib/bc adjust config.h PR: closes 4183
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/bc/COPYING341
-rw-r--r--gnu/usr.bin/bc/Makefile27
-rw-r--r--gnu/usr.bin/bc/bc.1732
-rw-r--r--gnu/usr.bin/bc/bc.y615
-rw-r--r--gnu/usr.bin/bc/bcdefs.h154
-rw-r--r--gnu/usr.bin/bc/config.h1
-rw-r--r--gnu/usr.bin/bc/const.h91
-rw-r--r--gnu/usr.bin/bc/execute.c785
-rw-r--r--gnu/usr.bin/bc/global.c42
-rw-r--r--gnu/usr.bin/bc/global.h125
-rw-r--r--gnu/usr.bin/bc/load.c333
-rw-r--r--gnu/usr.bin/bc/main.c204
-rw-r--r--gnu/usr.bin/bc/math.h40
-rw-r--r--gnu/usr.bin/bc/number.c1419
-rw-r--r--gnu/usr.bin/bc/number.h60
-rw-r--r--gnu/usr.bin/bc/proto.h160
-rw-r--r--gnu/usr.bin/bc/scan.l196
-rw-r--r--gnu/usr.bin/bc/storage.c963
-rw-r--r--gnu/usr.bin/bc/util.c820
-rw-r--r--gnu/usr.bin/bc/version.h3
20 files changed, 22 insertions, 7089 deletions
diff --git a/gnu/usr.bin/bc/COPYING b/gnu/usr.bin/bc/COPYING
deleted file mode 100644
index 86cf81a..0000000
--- a/gnu/usr.bin/bc/COPYING
+++ /dev/null
@@ -1,341 +0,0 @@
-
- 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/gnu/usr.bin/bc/Makefile b/gnu/usr.bin/bc/Makefile
index e4a2738..7c0557c 100644
--- a/gnu/usr.bin/bc/Makefile
+++ b/gnu/usr.bin/bc/Makefile
@@ -1,10 +1,25 @@
-PROG= bc
+# $Id$
-BCSRCS= execute.c global.c load.c main.c number.c storage.c util.c
-GENSRCS= bc.c scan.c
-SRCS= ${GENSRCS} ${BCSRCS}
+.include "${.CURDIR}/../Makefile.inc"
-CFLAGS+= -D_POSIX_SOURCE -I.
-CLEANFILES+= ${GENSRCS} y.tab.h
+.PATH: ${.CURDIR}/../../../contrib/bc/bc \
+ ${.CURDIR}/../../../contrib/bc/lib \
+ ${.CURDIR}/../../../contrib/bc/doc
+
+PROG= bc
+BCSRCS= execute.c global.c load.c main.c storage.c util.c \
+ number.c getopt.c getopt1.c
+GENSRCS= bc.c scan.c
+SRCS= ${GENSRCS} ${BCSRCS}
+MAN1= bc.1
+
+YACC= bison -y
+
+CFLAGS+= -DHAVE_VPRINTF=1 -DSTDC_HEADERS=1 -DHAVE_ISGRAPH=1 \
+ -DHAVE_LIMITS_H=1 -DHAVE_STDARG_H=1 -DHAVE_STDDEF_H=1 \
+ -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 \
+ -I${.CURDIR}/../../../contrib/bc/h -I.
+
+CLEANFILES+= ${GENSRCS} y.tab.h
.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/bc/bc.1 b/gnu/usr.bin/bc/bc.1
deleted file mode 100644
index 0244de0..0000000
--- a/gnu/usr.bin/bc/bc.1
+++ /dev/null
@@ -1,732 +0,0 @@
-.\"
-.\" bc.1 - the *roff document processor source for the bc manual
-.\"
-.\" This file is part of bc written initially for MINIX.
-.\" Copyright (C) 1991, 1992, 1993, 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 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
-.\"
-.\" $Id$
-.\"
-.TH bc 1 .\" "Command Manual" v1.03 "Nov 2, 1994"
-.SH NAME
-bc - An arbitrary precision calculator language
-.SH SYNTAX
-\fBbc\fR [ \fB-lws\fR ] [ \fI file ...\fR ]
-.SH VERSION
-This man page documents GNU bc version 1.03.
-.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.
-.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.
-.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 (F). 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
-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 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 ) \fBthen\fR 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 in radians.
-.IP "c (\fIx\fR)"
-The cosine of x in radians.
-.IP "a (\fIx\fR)"
-The arctangent of x.
-.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 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 have array parameters. Other implementations
-of \fBbc\fR may have 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 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.
-.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/gnu/usr.bin/bc/bc.y b/gnu/usr.bin/bc/bc.y
deleted file mode 100644
index 2c888c3..0000000
--- a/gnu/usr.bin/bc/bc.y
+++ /dev/null
@@ -1,615 +0,0 @@
-%{
-/* bc.y: The grammar for a POSIX compatable bc processor with some
- extensions to the language. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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> MUL_OP
-/* '*', '/', '%' */
-%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' */
-
-/* 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 MUL_OP
-%right '^'
-%nonassoc UNARY_MINUS
-%nonassoc INCR_DECR
-
-%%
-program : /* empty */
- {
- $$ = 0;
- if (interactive)
- {
- printf ("%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_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);
- }
- 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);
- }
- 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);
- }
- ')' 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;
- }
- statement
-function : Define NAME '(' opt_parameter_list ')' '{'
- NEWLINE opt_auto_define_list
- {
- /* Check auto list against parameter list? */
- check_params ($4,$8);
- sprintf (genstr, "F%d,%s.%s[",
- lookup($2,FUNCTDEF),
- arg_str ($4), arg_str ($8));
- generate (genstr);
- free_args ($4);
- free_args ($8);
- $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)); }
- | NAME '[' ']'
- { $$ = nextarg (NULL, lookup ($1,ARRAY)); }
- | define_list ',' NAME
- { $$ = nextarg ($1, lookup ($3,SIMPLE)); }
- | define_list ',' NAME '[' ']'
- { $$ = nextarg ($1, lookup ($3,ARRAY)); }
- ;
-opt_argument_list : /* empty */
- { $$ = NULL; }
- | argument_list
- ;
-argument_list : expression
- {
- if ($1 > 1) warn ("comparison in argument");
- $$ = nextarg (NULL,0);
- }
- | NAME '[' ']'
- {
- sprintf (genstr, "K%d:", -lookup ($1,ARRAY));
- generate (genstr);
- $$ = nextarg (NULL,1);
- }
- | argument_list ',' expression
- {
- if ($3 > 1) warn ("comparison in argument");
- $$ = nextarg ($1,0);
- }
- | argument_list ',' NAME '[' ']'
- {
- sprintf (genstr, "K%d:", -lookup ($3,ARRAY));
- generate (genstr);
- $$ = nextarg ($1,1);
- }
- ;
-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 MUL_OP expression
- {
- genstr[0] = $2;
- genstr[1] = 0;
- generate (genstr);
- $$ = $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; }
- | Last
- { $$ = 3;
- warn ("Last variable");
- }
- ;
-%%
diff --git a/gnu/usr.bin/bc/bcdefs.h b/gnu/usr.bin/bc/bcdefs.h
deleted file mode 100644
index 455530d..0000000
--- a/gnu/usr.bin/bc/bcdefs.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/* bcdefs.h: The single file to include all constants and type definitions. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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 the configuration file. */
-#include "config.h"
-
-/* Standard includes for all files. */
-#include <stdio.h>
-#include <sys/types.h>
-#include <ctype.h>
-#ifdef STRINGS_H
-#include <strings.h>
-#else
-#include <string.h>
-#endif
-#ifndef NO_LIMITS
-#include <limits.h>
-#endif
-
-/* Include the other definitions. */
-#include "const.h"
-#include "number.h"
-
-
-/* These definitions define all the structures used in
- code and data storage. This includes the representation of
- labels. The "guiding" principle is to make structures that
- take a minimum of space when unused but can be built to contain
- the full structures. */
-
-/* Labels are first. Labels are generated sequentially in functions
- and full code. They just "point" to a single bye in the code. The
- "address" is the byte number. The byte number is used to get an
- actual character pointer. */
-
-typedef struct bc_label_group
- {
- long l_adrs [ BC_LABEL_GROUP ];
- struct bc_label_group *l_next;
- } bc_label_group;
-
-
-/* Each function has its own code segments and labels. There can be
- no jumps between functions so labels are unique to a function. */
-
-typedef struct arg_list
- {
- int av_name;
- struct arg_list *next;
- } arg_list;
-
-typedef struct
- {
- char f_defined; /* Is this function defined yet. */
- char *f_body[BC_MAX_SEGS];
- int f_code_size;
- bc_label_group *f_label;
- arg_list *f_params;
- arg_list *f_autos;
- } bc_function;
-
-/* Code addresses. */
-typedef struct {
- int pc_func;
- int pc_addr;
- } program_counter;
-
-
-/* Variables are "pushable" (auto) and thus we need a stack mechanism.
- This is built into the variable record. */
-
-typedef struct bc_var
- {
- bc_num v_value;
- struct bc_var *v_next;
- } bc_var;
-
-
-/* bc arrays can also be "auto" variables and thus need the same
- kind of stacking mechanisms. */
-
-typedef struct bc_array_node
- {
- union
- {
- bc_num n_num [NODE_SIZE];
- struct bc_array_node *n_down [NODE_SIZE];
- } n_items;
- } bc_array_node;
-
-typedef struct bc_array
- {
- bc_array_node *a_tree;
- short a_depth;
- } bc_array;
-
-typedef struct bc_var_array
- {
- bc_array *a_value;
- char a_param;
- struct bc_var_array *a_next;
- } bc_var_array;
-
-
-/* For the stacks, execution and function, we need records to allow
- for arbitrary size. */
-
-typedef struct estack_rec {
- bc_num s_num;
- struct estack_rec *s_next;
-} estack_rec;
-
-typedef struct fstack_rec {
- int s_val;
- struct fstack_rec *s_next;
-} fstack_rec;
-
-
-/* The following are for the name tree. */
-
-typedef struct id_rec {
- char *id; /* The program name. */
- /* A name == 0 => nothing assigned yet. */
- int a_name; /* The array variable name (number). */
- int f_name; /* The function name (number). */
- int v_name; /* The variable name (number). */
- short balance; /* For the balanced tree. */
- struct id_rec *left, *right; /* Tree pointers. */
-} id_rec;
diff --git a/gnu/usr.bin/bc/config.h b/gnu/usr.bin/bc/config.h
index a9bd0be..abdc702 100644
--- a/gnu/usr.bin/bc/config.h
+++ b/gnu/usr.bin/bc/config.h
@@ -2,3 +2,4 @@
#ifndef __STDC__
#define VARARGS
#endif
+#define YYTEXT_POINTER 1
diff --git a/gnu/usr.bin/bc/const.h b/gnu/usr.bin/bc/const.h
deleted file mode 100644
index 1b55adc..0000000
--- a/gnu/usr.bin/bc/const.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* const.h: Constants for bc. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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
-
-*************************************************************************/
-
-
-/* Define INT_MAX and LONG_MAX if not defined. Assuming 32 bits... */
-
-#ifdef NO_LIMITS
-#define INT_MAX 0x7FFFFFFF
-#define LONG_MAX 0x7FFFFFFF
-#endif
-
-
-/* Define constants in some reasonable size. The next 4 constants are
- POSIX constants. */
-#if !defined(_POSIX_SOURCE)
-#define BC_BASE_MAX INT_MAX
-#define BC_SCALE_MAX INT_MAX
-#define BC_STRING_MAX INT_MAX
-
-/* Definitions for arrays. */
-
-#define BC_DIM_MAX 65535 /* this should be NODE_SIZE^NODE_DEPTH-1 */
-#endif
-
-#define NODE_SIZE 16 /* Must be a power of 2. */
-#define NODE_MASK 0xf /* Must be NODE_SIZE-1. */
-#define NODE_SHIFT 4 /* Number of 1 bits in NODE_MASK. */
-#define NODE_DEPTH 4
-
-
-/* Other BC limits defined but not part of POSIX. */
-
-#define BC_LABEL_GROUP 64
-#define BC_LABEL_LOG 6
-#define BC_MAX_SEGS 16 /* Code segments. */
-#define BC_SEG_SIZE 1024
-#define BC_SEG_LOG 10
-
-/* Maximum number of variables, arrays and functions and the
- allocation increment for the dynamic arrays. */
-
-#define MAX_STORE 32767
-#define STORE_INCR 32
-
-/* Other interesting constants. */
-
-#define FALSE 0
-#define TRUE 1
-
-/* for use with lookup (). */
-#define SIMPLE 0
-#define ARRAY 1
-#define FUNCT 2
-#define FUNCTDEF 3
-
-#define EXTERN extern
-#ifdef __STDC__
-#define CONST const
-#define VOID void
-#else
-#define CONST
-#define VOID
-#endif
-
-/* Include the version definition. */
-#include "version.h"
diff --git a/gnu/usr.bin/bc/execute.c b/gnu/usr.bin/bc/execute.c
deleted file mode 100644
index 1a89506..0000000
--- a/gnu/usr.bin/bc/execute.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/* execute.c - run a bc program. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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_char (ch);
- else
- {
- ch = byte(&pc);
- if (ch == '"') break;
- switch (ch)
- {
- case 'a': out_char (007); break;
- case 'b': out_char ('\b'); break;
- case 'f': out_char ('\f'); break;
- case 'n': out_char ('\n'); break;
- case 'q': out_char ('"'); break;
- case 'r': out_char ('\r'); break;
- case 't': out_char ('\t'); break;
- case '\\': out_char ('\\'); break;
- default: break;
- }
- }
- if (interactive) 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 (3); /* Special variable "last". */
- if (interactive) fflush (stdout);
- 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);
- 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_char (ch);
- if (interactive) 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);
- 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);
- 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);
- 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);
- 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);
- }
-
- /* Final work. */
- if (negative)
- bc_sub (_zero_, build, &build);
-
- 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/gnu/usr.bin/bc/global.c b/gnu/usr.bin/bc/global.c
deleted file mode 100644
index fc44ff6..0000000
--- a/gnu/usr.bin/bc/global.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* global.c: This defines the global variables. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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 "math.h"
-;
-#endif
diff --git a/gnu/usr.bin/bc/global.h b/gnu/usr.bin/bc/global.h
deleted file mode 100644
index 2b339a8..0000000
--- a/gnu/usr.bin/bc/global.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* global.h: The global variables for bc. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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
-
-*************************************************************************/
-
-
-/* The current break level's label. */
-EXTERN int break_label;
-
-/* The current if statement's else label or label after else. */
-EXTERN int if_label;
-
-/* The current for statement label for continuing the loop. */
-EXTERN int continue_label;
-
-/* Next available label number. */
-EXTERN int next_label;
-
-/* Byte code character storage. Used in many places for generation of code. */
-EXTERN char genstr[80];
-
-/* Count of characters printed to the output in compile_only mode. */
-EXTERN int out_count;
-
-/* Have we generated any code since the last initialization of the code
- generator. */
-EXTERN char did_gen;
-
-/* Is this run an interactive execution. (Is stdin a terminal?) */
-EXTERN char interactive;
-
-/* Just generate the byte code. -c flag. */
-EXTERN char compile_only;
-
-/* Load the standard math functions. -l flag. */
-EXTERN char use_math;
-
-/* Give a warning on use of any non-standard feature (non-POSIX). -w flag. */
-EXTERN char warn_not_std;
-
-/* Accept POSIX bc only! -s flag. */
-EXTERN char std_only;
-
-/* global variables for the bc machine. All will be dynamic in size.*/
-/* Function storage. main is (0) and functions (1-f_count) */
-
-EXTERN bc_function *functions;
-EXTERN char **f_names;
-EXTERN int f_count;
-
-/* Variable stoarge and reverse names. */
-
-EXTERN bc_var **variables;
-EXTERN char **v_names;
-EXTERN int v_count;
-
-/* Array Variable storage and reverse names. */
-
-EXTERN bc_var_array **arrays;
-EXTERN char **a_names;
-EXTERN int a_count;
-
-/* Execution stack. */
-EXTERN estack_rec *ex_stack;
-
-/* Function return stack. */
-EXTERN fstack_rec *fn_stack;
-
-/* Other "storage". */
-EXTERN int i_base;
-EXTERN int o_base;
-EXTERN int scale;
-EXTERN char c_code;
-EXTERN int out_col;
-EXTERN char runtime_error;
-EXTERN program_counter pc;
-
-/* Input Line numbers and other error information. */
-EXTERN int line_no;
-EXTERN int had_error;
-
-/* For larger identifiers, a tree, and how many "storage" locations
- have been allocated. */
-
-EXTERN int next_array;
-EXTERN int next_func;
-EXTERN int next_var;
-
-EXTERN id_rec *name_tree;
-
-/* For error message production */
-EXTERN char **g_argv;
-EXTERN int g_argc;
-EXTERN char is_std_in;
-
-/* defined in number.c */
-extern bc_num _zero_;
-extern bc_num _one_;
-
-/* For use with getopt. Do not declare them here.*/
-extern int optind;
-
diff --git a/gnu/usr.bin/bc/load.c b/gnu/usr.bin/bc/load.c
deleted file mode 100644
index 53466e5..0000000
--- a/gnu/usr.bin/bc/load.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* load.c: This code "loads" code into the code segments. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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;
- }
- 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);
- }
-
- /* 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);
- }
- 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/gnu/usr.bin/bc/main.c b/gnu/usr.bin/bc/main.c
deleted file mode 100644
index 57bcd8c..0000000
--- a/gnu/usr.bin/bc/main.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* main.c: The main program for bc. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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"
-
-/* Variables for processing multiple files. */
-char first_file;
-extern FILE *yyin;
-
-
-/* The main program for bc. */
-int
-main (argc, argv)
- int argc;
- char *argv[];
-{
- int ch;
-
- /* 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;
-
- /* Parse the command line */
- ch = getopt (argc, argv, "lcisvw");
- while (ch != EOF)
- {
- switch (ch)
- {
- case 'c': /* compile only */
- compile_only = TRUE;
- break;
- case 'l': /* math lib */
- use_math = TRUE;
- break;
- case 'i': /* force interactive */
- interactive = TRUE;
- break;
- case 'w': /* Non standard features give warnings. */
- warn_not_std = TRUE;
- break;
- case 's': /* Non standard features give errors. */
- std_only = TRUE;
- break;
- case 'v': /* Print the version. */
- printf ("%s\n", BC_VERSION);
- break;
- }
- ch = getopt (argc, argv, "lcisvw");
- }
-
- /* 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 ();
- g_argv = argv;
- g_argc = argc;
- is_std_in = FALSE;
- first_file = TRUE;
- if (!open_new_file ())
- exit (1);
-
- /* 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;
-
- /* 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. */
- while (optind < g_argc)
- {
- new_file = fopen (g_argv[optind], "r");
- if (new_file != NULL)
- {
- new_yy_file (new_file);
- optind++;
- return TRUE;
- }
- fprintf (stderr, "File %s is unavailable.\n", g_argv[optind++]);
- 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/gnu/usr.bin/bc/math.h b/gnu/usr.bin/bc/math.h
deleted file mode 100644
index fb5b03b..0000000
--- a/gnu/usr.bin/bc/math.h
+++ /dev/null
@@ -1,40 +0,0 @@
-"@iK20:s2:p@r\
-@iF1,4.5,6,7,8,9,10,11,12,13[l4:0<Z1:1s10:pl4:ns4:pN1:l2:s13:\
-pK6:l13:+K.44:l4:*+s11:pl4:cS1+s2:pN2:l4:1>Z3:l8:1+s8:pl4:K2:\
-/s4:pl2:1+s2:pJ2:N3:l11:s2:p1l4:+s12:pl4:s5:p1s6:pK2:s9:pN5:1\
-B6:J4:N7:l9:i9:pJ5:N6:l5:l4:*s5:l6:l9:*s6:/s7:pl7:0=Z8:l8:0>Z9:\
-N10:l8:d8:Z11:l12:l12:*s12:pJ10:N11:N9:l13:s2:pl10:Z12:1l12:/\
-RN12:l12:1/RN8:l12:l7:+s12:pJ7:N4:0R]@r\
-@iF2,4.7,8,9,10,11,12,13[l4:0{Z1:1K10:l2:^-RN1:l2:s13:pK6:l2:\
-+s2:pK2:s8:p0s9:pN2:l4:K2:}Z3:l8:K2:*s8:pl4:cRs4:pJ2:N3:N4:l4:\
-K.5:{Z5:l8:K2:*s8:pl4:cRs4:pJ4:N5:l4:1-l4:1+/s11:s12:pl11:l11:\
-*s10:pK3:s9:pN7:1B8:J6:N9:l9:K2:+s9:pJ7:N8:l11:l10:*s11:l9:/s7:\
-pl7:0=Z10:l8:l12:*s12:pl13:s2:pl12:1/RN10:l12:l7:+s12:pJ9:N6:\
-0R]@r\
-@iF3,4.7,9,10,11,14,12,13[l2:s13:pK1.1:l13:*K2:+s2:p1C4,0:s12:\
-pl4:0<Z1:1s10:pl4:ns4:pN1:0s2:pl4:l12:/K2:+K4:/s11:pl4:K4:l11:\
-*l12:*-s4:pl11:K2:%Z2:l4:ns4:pN2:l13:K2:+s2:pl4:s7:s12:pl4:nl4:\
-*s14:pK3:s9:pN4:1B5:J3:N6:l9:K2:+s9:pJ4:N5:l7:l14:l9:l9:1-*/*\
-s7:pl7:0=Z7:l13:s2:pl10:Z8:l12:n1/RN8:l12:1/RN7:l12:l7:+s12:p\
-J6:N3:0R]@r\
-@iF5,4.12[l2:1+s2:pl4:1C4,0:K2:*+C3,0:s12:pl2:1-s2:pl12:1/R0R]\
-@r\
-@iF4,4.5,7,8,9,10,11,14,12,13[1s10:pl4:0<Z1:1ns10:pl4:ns4:pN1:\
-l4:1=Z2:l2:K25:{Z3:K.7853981633974483096156608:l10:/RN3:l2:K40\
-:{Z4:K.7853981633974483096156608458198757210492:l10:/RN4:l2:K\
-60:{Z5:K.785398163397448309615660845819875721049292349843776455243736\
-:l10:/RN5:N2:l4:K.2:=Z6:l2:K25:{Z7:K.1973955598498807583700497\
-:l10:/RN7:l2:K40:{Z8:K.1973955598498807583700497651947902934475\
-:l10:/RN8:l2:K60:{Z9:K.197395559849880758370049765194790293447585103787852101517688\
-:l10:/RN9:N6:l2:s13:pl4:K.2:>Z10:l13:K5:+s2:pK.2:C4,0:s5:pN10:\
-l13:K3:+s2:pN11:l4:K.2:>Z12:l8:1+s8:pl4:K.2:-1l4:K.2:*+/s4:pJ11:N12:\
-l4:s11:s12:pl4:nl4:*s14:pK3:s9:pN14:1B15:J13:N16:l9:K2:+s9:pJ14:N15:\
-l11:l14:*s11:l9:/s7:pl7:0=Z17:l13:s2:pl8:l5:*l12:+l10:/RN17:l12:\
-l7:+s12:pJ16:N13:0R]@r\
-@iF6,11,4.5,6,7,8,9,10,14,12,13[l2:s13:p0s2:pl11:1/s11:pl11:0\
-<Z1:l11:ns11:pl11:K2:%1=Z2:1s10:pN2:N1:1s8:pK2:s9:pN4:l9:l11:\
-{B5:J3:N6:l9:i9:pJ4:N5:l8:l9:*s8:pJ6:N3:K1.5:l13:*s2:pl4:l11:\
-^K2:l11:^/l8:/s8:p1s7:s12:pl4:nl4:*K4:/s14:pK1.5:l13:*s2:p1s9:\
-pN8:1B9:J7:N10:l9:i9:pJ8:N9:l7:l14:*l9:/l11:l9:+/s7:pl7:0=Z11:\
-l13:s2:pl10:Z12:l8:nl12:*1/RN12:l8:l12:*1/RN11:l12:l7:+s12:pJ10:N7:\
-0R]@r"
diff --git a/gnu/usr.bin/bc/number.c b/gnu/usr.bin/bc/number.c
deleted file mode 100644
index ce078fe..0000000
--- a/gnu/usr.bin/bc/number.c
+++ /dev/null
@@ -1,1419 +0,0 @@
-/* number.c: Implements arbitrary precision numbers. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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 "proto.h"
-
-/* Storage used for special numbers. */
-bc_num _zero_;
-bc_num _one_;
-bc_num _two_;
-
-
-/* "Frees" a bc_num NUM. Actually decreases reference count and only
- frees the storage if reference count is zero. */
-
-void
-free_num (num)
- bc_num *num;
-{
- if (*num == NULL) return;
- (*num)->n_refs--;
- if ((*num)->n_refs == 0) free(*num);
- *num = NULL;
-}
-
-
-/* new_num allocates a number and sets fields to known values. */
-
-bc_num
-new_num (length, scale)
- int length, scale;
-{
- bc_num temp;
-
- temp = (bc_num) malloc (sizeof(bc_struct)+length+scale);
- if (temp == NULL) out_of_memory ();
- temp->n_sign = PLUS;
- temp->n_len = length;
- temp->n_scale = scale;
- temp->n_refs = 1;
- temp->n_value[0] = 0;
- return temp;
-}
-
-
-/* Intitialize the number package! */
-
-void
-init_numbers ()
-{
- _zero_ = new_num (1,0);
- _one_ = new_num (1,0);
- _one_->n_value[0] = 1;
- _two_ = new_num (1,0);
- _two_->n_value[0] = 2;
-}
-
-
-/* Make a copy of a number! Just increments the reference count! */
-
-bc_num
-copy_num (num)
- bc_num num;
-{
- num->n_refs++;
- return num;
-}
-
-
-/* Initialize a number NUM by making it a copy of zero. */
-
-void
-init_num (num)
- bc_num *num;
-{
- *num = copy_num (_zero_);
-}
-
-
-/* Convert an integer VAL to a bc number NUM. */
-
-void
-int2num (num, val)
- bc_num *num;
- int val;
-{
- char buffer[30];
- char *bptr, *vptr;
- int ix = 1;
- char neg = 0;
-
- /* Sign. */
- if (val < 0)
- {
- neg = 1;
- val = -val;
- }
-
- /* Get things going. */
- bptr = buffer;
- *bptr++ = val % 10;
- val = val / 10;
-
- /* Extract remaining digits. */
- while (val != 0)
- {
- *bptr++ = val % 10;
- val = val / 10;
- ix++; /* Count the digits. */
- }
-
- /* Make the number. */
- free_num (num);
- *num = new_num (ix, 0);
- if (neg) (*num)->n_sign = MINUS;
-
- /* Assign the digits. */
- vptr = (*num)->n_value;
- while (ix-- > 0)
- *vptr++ = *--bptr;
-}
-
-
-/* Convert a number NUM to a long. The function returns only the integer
- part of the number. For numbers that are too large to represent as
- a long, this function returns a zero. This can be detected by checking
- the NUM for zero after having a zero returned. */
-
-long
-num2long (num)
- bc_num num;
-{
- long val;
- char *nptr;
- int index;
-
- /* Extract the int value, ignore the fraction. */
- val = 0;
- nptr = num->n_value;
- for (index=num->n_len; (index>0) && (val<=(LONG_MAX/10)); index--)
- val = val*10 + *nptr++;
-
- /* Check for overflow. If overflow, return zero. */
- if (index>0) val = 0;
- if (val < 0) val = 0;
-
- /* Return the value. */
- if (num->n_sign == PLUS)
- return (val);
- else
- return (-val);
-}
-
-
-/* The following are some math routines for numbers. */
-_PROTOTYPE(static int _do_compare, (bc_num n1, bc_num n2, int use_sign,
- int ignore_last));
-_PROTOTYPE(static void _rm_leading_zeros, (bc_num num));
-_PROTOTYPE(static bc_num _do_add, (bc_num n1, bc_num n2));
-_PROTOTYPE(static bc_num _do_sub, (bc_num n1, bc_num n2));
-_PROTOTYPE(static void _one_mult, (unsigned char *num, int size, int digit,
- unsigned char *result));
-
-
-
-/* Compare two bc numbers. Return value is 0 if equal, -1 if N1 is less
- than N2 and +1 if N1 is greater than N2. If USE_SIGN is false, just
- compare the magnitudes. */
-
-static int
-_do_compare (n1, n2, use_sign, ignore_last)
- bc_num n1, n2;
- int use_sign;
- int ignore_last;
-{
- char *n1ptr, *n2ptr;
- int count;
-
- /* First, compare signs. */
- if (use_sign && n1->n_sign != n2->n_sign)
- {
- if (n1->n_sign == PLUS)
- return (1); /* Positive N1 > Negative N2 */
- else
- return (-1); /* Negative N1 < Positive N1 */
- }
-
- /* Now compare the magnitude. */
- if (n1->n_len != n2->n_len)
- {
- if (n1->n_len > n2->n_len)
- {
- /* Magnitude of n1 > n2. */
- if (!use_sign || n1->n_sign == PLUS)
- return (1);
- else
- return (-1);
- }
- else
- {
- /* Magnitude of n1 < n2. */
- if (!use_sign || n1->n_sign == PLUS)
- return (-1);
- else
- return (1);
- }
- }
-
- /* If we get here, they have the same number of integer digits.
- check the integer part and the equal length part of the fraction. */
- count = n1->n_len + MIN (n1->n_scale, n2->n_scale);
- n1ptr = n1->n_value;
- n2ptr = n2->n_value;
-
- while ((count > 0) && (*n1ptr == *n2ptr))
- {
- n1ptr++;
- n2ptr++;
- count--;
- }
- if (ignore_last && count == 1 && n1->n_scale == n2->n_scale)
- return (0);
- if (count != 0)
- {
- if (*n1ptr > *n2ptr)
- {
- /* Magnitude of n1 > n2. */
- if (!use_sign || n1->n_sign == PLUS)
- return (1);
- else
- return (-1);
- }
- else
- {
- /* Magnitude of n1 < n2. */
- if (!use_sign || n1->n_sign == PLUS)
- return (-1);
- else
- return (1);
- }
- }
-
- /* They are equal up to the last part of the equal part of the fraction. */
- if (n1->n_scale != n2->n_scale)
- if (n1->n_scale > n2->n_scale)
- {
- for (count = n1->n_scale-n2->n_scale; count>0; count--)
- if (*n1ptr++ != 0)
- {
- /* Magnitude of n1 > n2. */
- if (!use_sign || n1->n_sign == PLUS)
- return (1);
- else
- return (-1);
- }
- }
- else
- {
- for (count = n2->n_scale-n1->n_scale; count>0; count--)
- if (*n2ptr++ != 0)
- {
- /* Magnitude of n1 < n2. */
- if (!use_sign || n1->n_sign == PLUS)
- return (-1);
- else
- return (1);
- }
- }
-
- /* They must be equal! */
- return (0);
-}
-
-
-/* This is the "user callable" routine to compare numbers N1 and N2. */
-
-int
-bc_compare (n1, n2)
- bc_num n1, n2;
-{
- return _do_compare (n1, n2, TRUE, FALSE);
-}
-
-
-/* In some places we need to check if the number NUM is zero. */
-
-char
-is_zero (num)
- bc_num num;
-{
- int count;
- char *nptr;
-
- /* Quick check. */
- if (num == _zero_) return TRUE;
-
- /* Initialize */
- count = num->n_len + num->n_scale;
- nptr = num->n_value;
-
- /* The check */
- while ((count > 0) && (*nptr++ == 0)) count--;
-
- if (count != 0)
- return FALSE;
- else
- return TRUE;
-}
-
-
-/* In some places we need to check if the number is negative. */
-
-char
-is_neg (num)
- bc_num num;
-{
- return num->n_sign == MINUS;
-}
-
-
-/* For many things, we may have leading zeros in a number NUM.
- _rm_leading_zeros just moves the data to the correct
- place and adjusts the length. */
-
-static void
-_rm_leading_zeros (num)
- bc_num num;
-{
- int bytes;
- char *dst, *src;
-
- /* Do a quick check to see if we need to do it. */
- if (*num->n_value != 0) return;
-
- /* The first digit is 0, find the first non-zero digit in the 10's or
- greater place. */
- bytes = num->n_len;
- src = num->n_value;
- while (bytes > 1 && *src == 0) src++, bytes--;
- num->n_len = bytes;
- bytes += num->n_scale;
- dst = num->n_value;
- while (bytes-- > 0) *dst++ = *src++;
-
-}
-
-
-/* Perform addition: N1 is added to N2 and the value is
- returned. The signs of N1 and N2 are ignored. */
-
-static bc_num
-_do_add (n1, n2)
- bc_num n1, n2;
-{
- bc_num sum;
- int sum_scale, sum_digits;
- char *n1ptr, *n2ptr, *sumptr;
- int carry, n1bytes, n2bytes;
-
- /* Prepare sum. */
- sum_scale = MAX (n1->n_scale, n2->n_scale);
- sum_digits = MAX (n1->n_len, n2->n_len) + 1;
- sum = new_num (sum_digits,sum_scale);
-
- /* Start with the fraction part. Initialize the pointers. */
- n1bytes = n1->n_scale;
- n2bytes = n2->n_scale;
- n1ptr = (char *) (n1->n_value + n1->n_len + n1bytes - 1);
- n2ptr = (char *) (n2->n_value + n2->n_len + n2bytes - 1);
- sumptr = (char *) (sum->n_value + sum_scale + sum_digits - 1);
-
- /* Add the fraction part. First copy the longer fraction.*/
- if (n1bytes != n2bytes)
- {
- if (n1bytes > n2bytes)
- while (n1bytes>n2bytes)
- { *sumptr-- = *n1ptr--; n1bytes--;}
- else
- while (n2bytes>n1bytes)
- { *sumptr-- = *n2ptr--; n2bytes--;}
- }
-
- /* Now add the remaining fraction part and equal size integer parts. */
- n1bytes += n1->n_len;
- n2bytes += n2->n_len;
- carry = 0;
- while ((n1bytes > 0) && (n2bytes > 0))
- {
- *sumptr = *n1ptr-- + *n2ptr-- + carry;
- if (*sumptr > 9)
- {
- carry = 1;
- *sumptr -= 10;
- }
- else
- carry = 0;
- sumptr--;
- n1bytes--;
- n2bytes--;
- }
-
- /* Now add carry the longer integer part. */
- if (n1bytes == 0)
- { n1bytes = n2bytes; n1ptr = n2ptr; }
- while (n1bytes-- > 0)
- {
- *sumptr = *n1ptr-- + carry;
- if (*sumptr > 9)
- {
- carry = 1;
- *sumptr -= 10;
- }
- else
- carry = 0;
- sumptr--;
- }
-
- /* Set final carry. */
- if (carry == 1)
- *sumptr += 1;
-
- /* Adjust sum and return. */
- _rm_leading_zeros (sum);
- return sum;
-}
-
-
-/* Perform subtraction: N2 is subtracted from N1 and the value is
- returned. The signs of N1 and N2 are ignored. Also, N1 is
- assumed to be larger than N2. */
-
-static bc_num
-_do_sub (n1, n2)
- bc_num n1, n2;
-{
- bc_num diff;
- int diff_scale, diff_len;
- int min_scale, min_len;
- char *n1ptr, *n2ptr, *diffptr;
- int borrow, count, val;
-
- /* Allocate temporary storage. */
- diff_len = MAX (n1->n_len, n2->n_len);
- diff_scale = MAX (n1->n_scale, n2->n_scale);
- min_len = MIN (n1->n_len, n2->n_len);
- min_scale = MIN (n1->n_scale, n2->n_scale);
- diff = new_num (diff_len, diff_scale);
-
- /* Initialize the subtract. */
- n1ptr = (char *) (n1->n_value + n1->n_len + n1->n_scale -1);
- n2ptr = (char *) (n2->n_value + n2->n_len + n2->n_scale -1);
- diffptr = (char *) (diff->n_value + diff_len + diff_scale -1);
-
- /* Subtract the numbers. */
- borrow = 0;
-
- /* Take care of the longer scaled number. */
- if (n1->n_scale != min_scale)
- {
- /* n1 has the longer scale */
- for (count = n1->n_scale - min_scale; count > 0; count--)
- *diffptr-- = *n1ptr--;
- }
- else
- {
- /* n2 has the longer scale */
- for (count = n2->n_scale - min_scale; count > 0; count--)
- {
- val = - *n2ptr-- - borrow;
- if (val < 0)
- {
- val += 10;
- borrow = 1;
- }
- else
- borrow = 0;
- *diffptr-- = val;
- }
- }
-
- /* Now do the equal length scale and integer parts. */
-
- for (count = 0; count < min_len + min_scale; count++)
- {
- val = *n1ptr-- - *n2ptr-- - borrow;
- if (val < 0)
- {
- val += 10;
- borrow = 1;
- }
- else
- borrow = 0;
- *diffptr-- = val;
- }
-
- /* If n1 has more digits then n2, we now do that subtract. */
- if (diff_len != min_len)
- {
- for (count = diff_len - min_len; count > 0; count--)
- {
- val = *n1ptr-- - borrow;
- if (val < 0)
- {
- val += 10;
- borrow = 1;
- }
- else
- borrow = 0;
- *diffptr-- = val;
- }
- }
-
- /* Clean up and return. */
- _rm_leading_zeros (diff);
- return diff;
-}
-
-
-/* Here is the full add routine that takes care of negative numbers.
- N1 is added to N2 and the result placed into RESULT. */
-
-void
-bc_add ( n1, n2, result)
- bc_num n1, n2, *result;
-{
- bc_num sum = 0;
- int cmp_res;
-
- if (n1->n_sign == n2->n_sign)
- {
- sum = _do_add (n1, n2);
- sum->n_sign = n1->n_sign;
- }
- else
- {
- /* subtraction must be done. */
- cmp_res = _do_compare (n1, n2, FALSE, FALSE); /* Compare magnitudes. */
- switch (cmp_res)
- {
- case -1:
- /* n1 is less than n2, subtract n1 from n2. */
- sum = _do_sub (n2, n1);
- sum->n_sign = n2->n_sign;
- break;
- case 0:
- /* They are equal! return zero! */
- sum = copy_num (_zero_);
- break;
- case 1:
- /* n2 is less than n1, subtract n2 from n1. */
- sum = _do_sub (n1, n2);
- sum->n_sign = n1->n_sign;
- }
- }
-
- /* Clean up and return. */
- free_num (result);
- *result = sum;
-}
-
-
-/* Here is the full subtract routine that takes care of negative numbers.
- N2 is subtracted from N1 and the result placed in RESULT. */
-
-void
-bc_sub ( n1, n2, result)
- bc_num n1, n2, *result;
-{
- bc_num diff = 0;
- int cmp_res;
-
- if (n1->n_sign != n2->n_sign)
- {
- diff = _do_add (n1, n2);
- diff->n_sign = n1->n_sign;
- }
- else
- {
- /* subtraction must be done. */
- cmp_res = _do_compare (n1, n2, FALSE, FALSE); /* Compare magnitudes. */
- switch (cmp_res)
- {
- case -1:
- /* n1 is less than n2, subtract n1 from n2. */
- diff = _do_sub (n2, n1);
- diff->n_sign = (n2->n_sign == PLUS ? MINUS : PLUS);
- break;
- case 0:
- /* They are equal! return zero! */
- diff = copy_num (_zero_);
- break;
- case 1:
- /* n2 is less than n1, subtract n2 from n1. */
- diff = _do_sub (n1, n2);
- diff->n_sign = n1->n_sign;
- break;
- }
- }
-
- /* Clean up and return. */
- free_num (result);
- *result = diff;
-}
-
-
-/* The multiply routine. N2 time N1 is put int PROD with the scale of
- the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)).
- */
-
-void
-bc_multiply (n1, n2, prod, scale)
- bc_num n1, n2, *prod;
- int scale;
-{
- bc_num pval; /* For the working storage. */
- char *n1ptr, *n2ptr, *pvptr; /* Work pointers. */
- char *n1end, *n2end; /* To the end of n1 and n2. */
-
- int indx;
- int len1, len2, total_digits;
- long sum;
- int full_scale, prod_scale;
- int toss;
-
- /* Initialize things. */
- len1 = n1->n_len + n1->n_scale;
- len2 = n2->n_len + n2->n_scale;
- total_digits = len1 + len2;
- full_scale = n1->n_scale + n2->n_scale;
- prod_scale = MIN(full_scale,MAX(scale,MAX(n1->n_scale,n2->n_scale)));
- toss = full_scale - prod_scale;
- pval = new_num (total_digits-full_scale, prod_scale);
- pval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );
- n1end = (char *) (n1->n_value + len1 - 1);
- n2end = (char *) (n2->n_value + len2 - 1);
- pvptr = (char *) (pval->n_value + total_digits - toss - 1);
- sum = 0;
-
- /* Here are the loops... */
- for (indx = 0; indx < toss; indx++)
- {
- n1ptr = (char *) (n1end - MAX(0, indx-len2+1));
- n2ptr = (char *) (n2end - MIN(indx, len2-1));
- while ((n1ptr >= n1->n_value) && (n2ptr <= n2end))
- sum += *n1ptr-- * *n2ptr++;
- sum = sum / 10;
- }
- for ( ; indx < total_digits-1; indx++)
- {
- n1ptr = (char *) (n1end - MAX(0, indx-len2+1));
- n2ptr = (char *) (n2end - MIN(indx, len2-1));
- while ((n1ptr >= n1->n_value) && (n2ptr <= n2end))
- sum += *n1ptr-- * *n2ptr++;
- *pvptr-- = sum % 10;
- sum = sum / 10;
- }
- *pvptr-- = sum;
-
- /* Assign to prod and clean up the number. */
- free_num (prod);
- *prod = pval;
- _rm_leading_zeros (*prod);
- if (is_zero (*prod))
- (*prod)->n_sign = PLUS;
-}
-
-
-/* Some utility routines for the divide: First a one digit multiply.
- NUM (with SIZE digits) is multiplied by DIGIT and the result is
- placed into RESULT. It is written so that NUM and RESULT can be
- the same pointers. */
-
-static void
-_one_mult (num, size, digit, result)
- unsigned char *num;
- int size, digit;
- unsigned char *result;
-{
- int carry, value;
- unsigned char *nptr, *rptr;
-
- if (digit == 0)
- memset (result, 0, size);
- else
- {
- if (digit == 1)
- memcpy (result, num, size);
- else
- {
- /* Initialize */
- nptr = (unsigned char *) (num+size-1);
- rptr = (unsigned char *) (result+size-1);
- carry = 0;
-
- while (size-- > 0)
- {
- value = *nptr-- * digit + carry;
- *rptr-- = value % 10;
- carry = value / 10;
- }
-
- if (carry != 0) *rptr = carry;
- }
- }
-}
-
-
-/* The full division routine. This computes N1 / N2. It returns
- 0 if the division is ok and the result is in QUOT. The number of
- digits after the decimal point is SCALE. It returns -1 if division
- by zero is tried. The algorithm is found in Knuth Vol 2. p237. */
-
-int
-bc_divide (n1, n2, quot, scale)
- bc_num n1, n2, *quot;
- int scale;
-{
- bc_num qval;
- unsigned char *num1, *num2;
- unsigned char *ptr1, *ptr2, *n2ptr, *qptr;
- int scale1, val;
- unsigned int len1, len2, scale2, qdigits, extra, count;
- unsigned int qdig, qguess, borrow, carry;
- unsigned char *mval;
- char zero;
- unsigned int norm;
-
- /* Test for divide by zero. */
- if (is_zero (n2)) return -1;
-
- /* Test for divide by 1. If it is we must truncate. */
- if (n2->n_scale == 0)
- {
- if (n2->n_len == 1 && *n2->n_value == 1)
- {
- qval = new_num (n1->n_len, scale);
- qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS);
- memset (&qval->n_value[n1->n_len],0,scale);
- memcpy (qval->n_value, n1->n_value,
- n1->n_len + MIN(n1->n_scale,scale));
- free_num (quot);
- *quot = qval;
- }
- }
-
- /* Set up the divide. Move the decimal point on n1 by n2's scale.
- Remember, zeros on the end of num2 are wasted effort for dividing. */
- scale2 = n2->n_scale;
- n2ptr = (unsigned char *) n2->n_value+n2->n_len+scale2-1;
- while ((scale2 > 0) && (*n2ptr-- == 0)) scale2--;
-
- len1 = n1->n_len + scale2;
- scale1 = n1->n_scale - scale2;
- if (scale1 < scale)
- extra = scale - scale1;
- else
- extra = 0;
- num1 = (unsigned char *) malloc (n1->n_len+n1->n_scale+extra+2);
- if (num1 == NULL) out_of_memory();
- memset (num1, 0, n1->n_len+n1->n_scale+extra+2);
- memcpy (num1+1, n1->n_value, n1->n_len+n1->n_scale);
-
- len2 = n2->n_len + scale2;
- num2 = (unsigned char *) malloc (len2+1);
- if (num2 == NULL) out_of_memory();
- memcpy (num2, n2->n_value, len2);
- *(num2+len2) = 0;
- n2ptr = num2;
- while (*n2ptr == 0)
- {
- n2ptr++;
- len2--;
- }
-
- /* Calculate the number of quotient digits. */
- if (len2 > len1+scale)
- {
- qdigits = scale+1;
- zero = TRUE;
- }
- else
- {
- zero = FALSE;
- if (len2>len1)
- qdigits = scale+1; /* One for the zero integer part. */
- else
- qdigits = len1-len2+scale+1;
- }
-
- /* Allocate and zero the storage for the quotient. */
- qval = new_num (qdigits-scale,scale);
- memset (qval->n_value, 0, qdigits);
-
- /* Allocate storage for the temporary storage mval. */
- mval = (unsigned char *) malloc (len2+1);
- if (mval == NULL) out_of_memory ();
-
- /* Now for the full divide algorithm. */
- if (!zero)
- {
- /* Normalize */
- norm = 10 / ((int)*n2ptr + 1);
- if (norm != 1)
- {
- _one_mult (num1, len1+scale1+extra+1, norm, num1);
- _one_mult (n2ptr, len2, norm, n2ptr);
- }
-
- /* Initialize divide loop. */
- qdig = 0;
- if (len2 > len1)
- qptr = (unsigned char *) qval->n_value+len2-len1;
- else
- qptr = (unsigned char *) qval->n_value;
-
- /* Loop */
- while (qdig <= len1+scale-len2)
- {
- /* Calculate the quotient digit guess. */
- if (*n2ptr == num1[qdig])
- qguess = 9;
- else
- qguess = (num1[qdig]*10 + num1[qdig+1]) / *n2ptr;
-
- /* Test qguess. */
- if (n2ptr[1]*qguess >
- (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10
- + num1[qdig+2])
- {
- qguess--;
- /* And again. */
- if (n2ptr[1]*qguess >
- (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10
- + num1[qdig+2])
- qguess--;
- }
-
- /* Multiply and subtract. */
- borrow = 0;
- if (qguess != 0)
- {
- *mval = 0;
- _one_mult (n2ptr, len2, qguess, mval+1);
- ptr1 = (unsigned char *) num1+qdig+len2;
- ptr2 = (unsigned char *) mval+len2;
- for (count = 0; count < len2+1; count++)
- {
- val = (int) *ptr1 - (int) *ptr2-- - borrow;
- if (val < 0)
- {
- val += 10;
- borrow = 1;
- }
- else
- borrow = 0;
- *ptr1-- = val;
- }
- }
-
- /* Test for negative result. */
- if (borrow == 1)
- {
- qguess--;
- ptr1 = (unsigned char *) num1+qdig+len2;
- ptr2 = (unsigned char *) n2ptr+len2-1;
- carry = 0;
- for (count = 0; count < len2; count++)
- {
- val = (int) *ptr1 + (int) *ptr2-- + carry;
- if (val > 9)
- {
- val -= 10;
- carry = 1;
- }
- else
- carry = 0;
- *ptr1-- = val;
- }
- if (carry == 1) *ptr1 = (*ptr1 + 1) % 10;
- }
-
- /* We now know the quotient digit. */
- *qptr++ = qguess;
- qdig++;
- }
- }
-
- /* Clean up and return the number. */
- qval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS );
- if (is_zero (qval)) qval->n_sign = PLUS;
- _rm_leading_zeros (qval);
- free_num (quot);
- *quot = qval;
-
- /* Clean up temporary storage. */
- free (mval);
- free (num1);
- free (num2);
-
- return 0; /* Everything is OK. */
-}
-
-
-/* Modulo for numbers. This computes NUM1 % NUM2 and puts the
- result in RESULT. */
-
-int
-bc_modulo (num1, num2, result, scale)
- bc_num num1, num2, *result;
- int scale;
-{
- bc_num temp;
- int rscale;
-
- /* Check for correct numbers. */
- if (is_zero (num2)) return -1;
-
- /* Calculate final scale. */
- rscale = MAX (num1->n_scale, num2->n_scale+scale);
- init_num (&temp);
-
- /* Calculate it. */
- bc_divide (num1, num2, &temp, scale);
- bc_multiply (temp, num2, &temp, rscale);
- bc_sub (num1, temp, result);
- free_num (&temp);
-
- return 0; /* Everything is OK. */
-}
-
-
-/* Raise NUM1 to the NUM2 power. The result is placed in RESULT.
- Maximum exponent is LONG_MAX. If a NUM2 is not an integer,
- only the integer part is used. */
-
-void
-bc_raise (num1, num2, result, scale)
- bc_num num1, num2, *result;
- int scale;
-{
- bc_num temp, power;
- long exponent;
- int rscale;
- char neg;
-
- /* Check the exponent for scale digits and convert to a long. */
- if (num2->n_scale != 0)
- rt_warn ("non-zero scale in exponent");
- exponent = num2long (num2);
- if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0))
- rt_error ("exponent too large in raise");
-
- /* Special case if exponent is a zero. */
- if (exponent == 0)
- {
- free_num (result);
- *result = copy_num (_one_);
- return;
- }
-
- /* Other initializations. */
- if (exponent < 0)
- {
- neg = TRUE;
- exponent = -exponent;
- rscale = scale;
- }
- else
- {
- neg = FALSE;
- rscale = MIN (num1->n_scale*exponent, MAX(scale, num1->n_scale));
- }
-
- /* Set initial value of temp. */
- power = copy_num (num1);
- while ((exponent & 1) == 0)
- {
- bc_multiply (power, power, &power, rscale);
- exponent = exponent >> 1;
- }
- temp = copy_num (power);
- exponent = exponent >> 1;
-
- /* Do the calculation. */
- while (exponent > 0)
- {
- bc_multiply (power, power, &power, rscale);
- if ((exponent & 1) == 1)
- bc_multiply (temp, power, &temp, rscale);
- exponent = exponent >> 1;
- }
-
- /* Assign the value. */
- if (neg)
- {
- bc_divide (_one_, temp, result, rscale);
- free_num (&temp);
- }
- else
- {
- free_num (result);
- *result = temp;
- }
- free_num (&power);
-}
-
-
-/* Take the square root NUM and return it in NUM with SCALE digits
- after the decimal place. */
-
-int
-bc_sqrt (num, scale)
- bc_num *num;
- int scale;
-{
- int rscale, cmp_res, done;
- int cscale;
- bc_num guess, guess1, point5;
-
- /* Initial checks. */
- cmp_res = bc_compare (*num, _zero_);
- if (cmp_res < 0)
- return 0; /* error */
- else
- {
- if (cmp_res == 0)
- {
- free_num (num);
- *num = copy_num (_zero_);
- return 1;
- }
- }
- cmp_res = bc_compare (*num, _one_);
- if (cmp_res == 0)
- {
- free_num (num);
- *num = copy_num (_one_);
- return 1;
- }
-
- /* Initialize the variables. */
- rscale = MAX (scale, (*num)->n_scale);
- init_num (&guess);
- init_num (&guess1);
- point5 = new_num (1,1);
- point5->n_value[1] = 5;
-
-
- /* Calculate the initial guess. */
- if (cmp_res < 0)
- /* The number is between 0 and 1. Guess should start at 1. */
- guess = copy_num (_one_);
- else
- {
- /* The number is greater than 1. Guess should start at 10^(exp/2). */
- int2num (&guess,10);
- int2num (&guess1,(*num)->n_len);
- bc_multiply (guess1, point5, &guess1, 0);
- guess1->n_scale = 0;
- bc_raise (guess, guess1, &guess, 0);
- free_num (&guess1);
- }
-
- /* Find the square root using Newton's algorithm. */
- done = FALSE;
- cscale = 2;
- while (!done)
- {
- free_num (&guess1);
- guess1 = copy_num (guess);
- bc_divide (*num,guess,&guess,cscale);
- bc_add (guess,guess1,&guess);
- bc_multiply (guess,point5,&guess,cscale);
- cmp_res = _do_compare (guess,guess1,FALSE,TRUE);
- if (cmp_res == 0)
- if (cscale < rscale+1)
- cscale = MIN (cscale*3, rscale+1);
- else
- done = TRUE;
- }
-
- /* Assign the number and clean up. */
- free_num (num);
- bc_divide (guess,_one_,num,rscale);
- free_num (&guess);
- free_num (&guess1);
- free_num (&point5);
- return 1;
-}
-
-
-/* The following routines provide output for bcd numbers package
- using the rules of POSIX bc for output. */
-
-/* This structure is used for saving digits in the conversion process. */
-typedef struct stk_rec {
- long digit;
- struct stk_rec *next;
-} stk_rec;
-
-/* The reference string for digits. */
-char ref_str[] = "0123456789ABCDEF";
-
-
-/* A special output routine for "multi-character digits." Exactly
- SIZE characters must be output for the value VAL. If SPACE is
- non-zero, we must output one space before the number. OUT_CHAR
- is the actual routine for writing the characters. */
-
-void
-out_long (val, size, space, out_char)
- long val;
- int size, space;
-#ifdef __STDC__
- void (*out_char)(int);
-#else
- void (*out_char)();
-#endif
-{
- char digits[40];
- int len, ix;
-
- if (space) (*out_char) (' ');
- sprintf (digits, "%ld", val);
- len = strlen (digits);
- while (size > len)
- {
- (*out_char) ('0');
- size--;
- }
- for (ix=0; ix < len; ix++)
- (*out_char) (digits[ix]);
-}
-
-/* Output of a bcd number. NUM is written in base O_BASE using OUT_CHAR
- as the routine to do the actual output of the characters. */
-
-void
-out_num (num, o_base, out_char)
- bc_num num;
- int o_base;
-#ifdef __STDC__
- void (*out_char)(int);
-#else
- void (*out_char)();
-#endif
-{
- char *nptr;
- int index, fdigit, pre_space;
- stk_rec *digits, *temp;
- bc_num int_part, frac_part, base, cur_dig, t_num, max_o_digit;
-
- /* The negative sign if needed. */
- if (num->n_sign == MINUS) (*out_char) ('-');
-
- /* Output the number. */
- if (is_zero (num))
- (*out_char) ('0');
- else
- if (o_base == 10)
- {
- /* The number is in base 10, do it the fast way. */
- nptr = num->n_value;
- if (num->n_len > 1 || *nptr != 0)
- for (index=num->n_len; index>0; index--)
- (*out_char) (BCD_CHAR(*nptr++));
- else
- nptr++;
-
- /* Now the fraction. */
- if (num->n_scale > 0)
- {
- (*out_char) ('.');
- for (index=0; index<num->n_scale; index++)
- (*out_char) (BCD_CHAR(*nptr++));
- }
- }
- else
- {
- /* The number is some other base. */
- digits = NULL;
- init_num (&int_part);
- bc_divide (num, _one_, &int_part, 0);
- init_num (&frac_part);
- init_num (&cur_dig);
- init_num (&base);
- bc_sub (num, int_part, &frac_part);
- /* Make the INT_PART and FRAC_PART positive. */
- int_part->n_sign = PLUS;
- frac_part->n_sign = PLUS;
- int2num (&base, o_base);
- init_num (&max_o_digit);
- int2num (&max_o_digit, o_base-1);
-
-
- /* Get the digits of the integer part and push them on a stack. */
- while (!is_zero (int_part))
- {
- bc_modulo (int_part, base, &cur_dig, 0);
- temp = (stk_rec *) malloc (sizeof(stk_rec));
- if (temp == NULL) out_of_memory();
- temp->digit = num2long (cur_dig);
- temp->next = digits;
- digits = temp;
- bc_divide (int_part, base, &int_part, 0);
- }
-
- /* Print the digits on the stack. */
- if (digits != NULL)
- {
- /* Output the digits. */
- while (digits != NULL)
- {
- temp = digits;
- digits = digits->next;
- if (o_base <= 16)
- (*out_char) (ref_str[ (int) temp->digit]);
- else
- out_long (temp->digit, max_o_digit->n_len, 1, out_char);
- free (temp);
- }
- }
-
- /* Get and print the digits of the fraction part. */
- if (num->n_scale > 0)
- {
- (*out_char) ('.');
- pre_space = 0;
- t_num = copy_num (_one_);
- while (t_num->n_len <= num->n_scale) {
- bc_multiply (frac_part, base, &frac_part, num->n_scale);
- fdigit = num2long (frac_part);
- int2num (&int_part, fdigit);
- bc_sub (frac_part, int_part, &frac_part);
- if (o_base <= 16)
- (*out_char) (ref_str[fdigit]);
- else {
- out_long (fdigit, max_o_digit->n_len, pre_space, out_char);
- pre_space = 1;
- }
- bc_multiply (t_num, base, &t_num, 0);
- }
- }
-
- /* Clean up. */
- free_num (&int_part);
- free_num (&frac_part);
- free_num (&base);
- free_num (&cur_dig);
- }
-}
-
-
-#if DEBUG > 0
-
-/* Debugging procedures. Some are just so one can call them from the
- debugger. */
-
-/* p_n prints the number NUM in base 10. */
-
-void
-p_n (num)
- bc_num num;
-{
- out_num (num, 10, out_char);
-}
-
-
-/* p_b prints a character array as if it was a string of bcd digits. */
-void
-p_v (name, num, len)
- char *name;
- unsigned char *num;
- int len;
-{
- int i;
- printf ("%s=", name);
- for (i=0; i<len; i++) printf ("%c",BCD_CHAR(num[i]));
- printf ("\n");
-}
-
-
-/* Convert strings to bc numbers. Base 10 only.*/
-
-void
-str2num (num, str, scale)
- bc_num *num;
- char *str;
- int scale;
-{
- int digits, strscale;
- char *ptr, *nptr;
- char zero_int;
-
- /* Prepare num. */
- free_num (num);
-
- /* Check for valid number and count digits. */
- ptr = str;
- digits = 0;
- strscale = 0;
- zero_int = FALSE;
- if ( (*ptr == '+') || (*ptr == '-')) ptr++; /* Sign */
- while (*ptr == '0') ptr++; /* Skip leading zeros. */
- while (isdigit(*ptr)) ptr++, digits++; /* digits */
- if (*ptr == '.') ptr++; /* decimal point */
- while (isdigit(*ptr)) ptr++, strscale++; /* digits */
- if ((*ptr != '\0') || (digits+strscale == 0))
- {
- *num = copy_num (_zero_);
- return;
- }
-
- /* Adjust numbers and allocate storage and initialize fields. */
- strscale = MIN(strscale, scale);
- if (digits == 0)
- {
- zero_int = TRUE;
- digits = 1;
- }
- *num = new_num (digits, strscale);
-
- /* Build the whole number. */
- ptr = str;
- if (*ptr == '-')
- {
- (*num)->n_sign = MINUS;
- ptr++;
- }
- else
- {
- (*num)->n_sign = PLUS;
- if (*ptr == '+') ptr++;
- }
- while (*ptr == '0') ptr++; /* Skip leading zeros. */
- nptr = (*num)->n_value;
- if (zero_int)
- {
- *nptr++ = 0;
- digits = 0;
- }
- for (;digits > 0; digits--)
- *nptr++ = CH_VAL(*ptr++);
-
-
- /* Build the fractional part. */
- if (strscale > 0)
- {
- ptr++; /* skip the decimal point! */
- for (;strscale > 0; strscale--)
- *nptr++ = CH_VAL(*ptr++);
- }
-}
-
-/* Convert a numbers to a string. Base 10 only.*/
-
-char
-*num2str (num)
- bc_num num;
-{
- char *str, *sptr;
- char *nptr;
- int index, signch;
-
- /* Allocate the string memory. */
- signch = ( num->n_sign == PLUS ? 0 : 1 ); /* Number of sign chars. */
- if (num->n_scale > 0)
- str = (char *) malloc (num->n_len + num->n_scale + 2 + signch);
- else
- str = (char *) malloc (num->n_len + 1 + signch);
- if (str == NULL) out_of_memory();
-
- /* The negative sign if needed. */
- sptr = str;
- if (signch) *sptr++ = '-';
-
- /* Load the whole number. */
- nptr = num->n_value;
- for (index=num->n_len; index>0; index--)
- *sptr++ = BCD_CHAR(*nptr++);
-
- /* Now the fraction. */
- if (num->n_scale > 0)
- {
- *sptr++ = '.';
- for (index=0; index<num->n_scale; index++)
- *sptr++ = BCD_CHAR(*nptr++);
- }
-
- /* Terminate the string and return it! */
- *sptr = '\0';
- return (str);
-}
-#endif
diff --git a/gnu/usr.bin/bc/number.h b/gnu/usr.bin/bc/number.h
deleted file mode 100644
index 325612e..0000000
--- a/gnu/usr.bin/bc/number.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* number.h: Arbitrary precision numbers header file. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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
-
-*************************************************************************/
-
-
-typedef enum {PLUS, MINUS} sign;
-
-typedef struct
- {
- sign n_sign;
- int n_len; /* The number of digits before the decimal point. */
- int n_scale; /* The number of digits after the decimal point. */
- int n_refs; /* The number of pointers to this number. */
- char n_value[1]; /* The storage. Not zero char terminated. It is
- allocated with all other fields. */
- } bc_struct;
-
-typedef bc_struct *bc_num;
-
-/* Some useful macros and constants. */
-
-#define CH_VAL(c) (c - '0')
-#define BCD_CHAR(d) (d + '0')
-
-#ifdef MIN
-#undef MIN
-#undef MAX
-#endif
-#define MAX(a,b) (a>b?a:b)
-#define MIN(a,b) (a>b?b:a)
-#define ODD(a) (a&1)
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
diff --git a/gnu/usr.bin/bc/proto.h b/gnu/usr.bin/bc/proto.h
deleted file mode 100644
index 37fb212..0000000
--- a/gnu/usr.bin/bc/proto.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* proto.h: Prototype function definitions for "external" functions. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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
-
-*************************************************************************/
-
-/* For the pc version using k&r ACK. (minix1.5 and earlier.) */
-#ifdef SHORTNAMES
-#define init_numbers i_numbers
-#define push_constant push__constant
-#define load_const in_load_const
-#define yy_get_next_buffer yyget_next_buffer
-#define yy_init_buffer yyinit_buffer
-#define yy_last_accepting_state yylast_accepting_state
-#define arglist1 arg1list
-#endif
-
-/* Include the standard library header files. */
-#include <unistd.h>
-#include <stdlib.h>
-
-/* Define the _PROTOTYPE macro if it is needed. */
-
-#ifndef _PROTOTYPE
-#ifdef __STDC__
-#define _PROTOTYPE(func, args) func args
-#else
-#define _PROTOTYPE(func, args) func()
-#endif
-#endif
-
-/* From execute.c */
-_PROTOTYPE(void stop_execution, (int));
-_PROTOTYPE(unsigned char byte, (program_counter *pc));
-_PROTOTYPE(void execute, (void));
-_PROTOTYPE(char prog_char, (void));
-_PROTOTYPE(char input_char, (void));
-_PROTOTYPE(void push_constant, (char (*in_char)(void), int conv_base));
-_PROTOTYPE(void push_b10_const, (program_counter *pc));
-_PROTOTYPE(void assign, (int c_code));
-
-/* From util.c */
-_PROTOTYPE(char *strcopyof, (char *str));
-_PROTOTYPE(arg_list *nextarg, (arg_list *args, int val));
-_PROTOTYPE(char *arg_str, (arg_list *args));
-_PROTOTYPE(char *call_str, (arg_list *args));
-_PROTOTYPE(void free_args, (arg_list *args));
-_PROTOTYPE(void check_params, (arg_list *params, arg_list *autos));
-_PROTOTYPE(void init_gen, (void));
-_PROTOTYPE(void generate, (char *str));
-_PROTOTYPE(void run_code, (void));
-_PROTOTYPE(void out_char, (int ch));
-_PROTOTYPE(id_rec *find_id, (id_rec *tree, char *id));
-_PROTOTYPE(int insert_id_rec, (id_rec **root, id_rec *new_id));
-_PROTOTYPE(void init_tree, (void));
-_PROTOTYPE(int lookup, (char *name, int namekind));
-_PROTOTYPE(char *bc_malloc, (int));
-_PROTOTYPE(void out_of_memory, (void));
-_PROTOTYPE(void welcome, (void));
-_PROTOTYPE(void warranty, (char *));
-_PROTOTYPE(void limits, (void));
-_PROTOTYPE(void yyerror, (char *str ,...));
-_PROTOTYPE(void warn, (char *mesg ,...));
-_PROTOTYPE(void rt_error, (char *mesg ,...));
-_PROTOTYPE(void rt_warn, (char *mesg ,...));
-
-/* From load.c */
-_PROTOTYPE(void init_load, (void));
-_PROTOTYPE(void addbyte, (int byte));
-_PROTOTYPE(void def_label, (long lab));
-_PROTOTYPE(long long_val, (char **str));
-_PROTOTYPE(void load_code, (char *code));
-
-/* From main.c */
-_PROTOTYPE(int main, (int argc , char *argv []));
-_PROTOTYPE(int open_new_file, (void));
-_PROTOTYPE(void new_yy_file, (FILE *file));
-_PROTOTYPE(void use_quit, (int));
-
-/* From number.c */
-_PROTOTYPE(void free_num, (bc_num *num));
-_PROTOTYPE(bc_num new_num, (int length, int scale));
-_PROTOTYPE(void init_numbers, (void));
-_PROTOTYPE(bc_num copy_num, (bc_num num));
-_PROTOTYPE(void init_num, (bc_num *num));
-_PROTOTYPE(void str2num, (bc_num *num, char *str, int scale));
-_PROTOTYPE(char *num2str, (bc_num num));
-_PROTOTYPE(void int2num, (bc_num *num, int val));
-_PROTOTYPE(long num2long, (bc_num num));
-_PROTOTYPE(int bc_compare, (bc_num n1, bc_num n2));
-_PROTOTYPE(char is_zero, (bc_num num));
-_PROTOTYPE(char is_neg, (bc_num num));
-_PROTOTYPE(void bc_add, (bc_num n1, bc_num n2, bc_num *result));
-_PROTOTYPE(void bc_sub, (bc_num n1, bc_num n2, bc_num *result));
-_PROTOTYPE(void bc_multiply, (bc_num n1, bc_num n2, bc_num *prod, int scale));
-_PROTOTYPE(int bc_divide, (bc_num n1, bc_num n2, bc_num *quot, int scale));
-_PROTOTYPE(int bc_modulo, (bc_num num1, bc_num num2, bc_num *result, int scale));
-_PROTOTYPE(void bc_raise, (bc_num num1, bc_num num2, bc_num *result, int scale));
-_PROTOTYPE(int bc_sqrt, (bc_num *num, int scale));
-_PROTOTYPE(void out_long, (long val, int size, int space,
- void (*out_char)(int)));
-_PROTOTYPE(void out_num, (bc_num num, int o_base, void (* out_char)(int)));
-
-
-/* From storage.c */
-_PROTOTYPE(void init_storage, (void));
-_PROTOTYPE(void more_functions, (void));
-_PROTOTYPE(void more_variables, (void));
-_PROTOTYPE(void more_arrays, (void));
-_PROTOTYPE(void clear_func, (int func ));
-_PROTOTYPE(int fpop, (void));
-_PROTOTYPE(void fpush, (int val ));
-_PROTOTYPE(void pop, (void));
-_PROTOTYPE(void push_copy, (bc_num num ));
-_PROTOTYPE(void push_num, (bc_num num ));
-_PROTOTYPE(char check_stack, (int depth ));
-_PROTOTYPE(bc_var *get_var, (int var_name ));
-_PROTOTYPE(bc_num *get_array_num, (int var_index, long index ));
-_PROTOTYPE(void store_var, (int var_name ));
-_PROTOTYPE(void store_array, (int var_name ));
-_PROTOTYPE(void load_var, (int var_name ));
-_PROTOTYPE(void load_array, (int var_name ));
-_PROTOTYPE(void decr_var, (int var_name ));
-_PROTOTYPE(void decr_array, (int var_name ));
-_PROTOTYPE(void incr_var, (int var_name ));
-_PROTOTYPE(void incr_array, (int var_name ));
-_PROTOTYPE(void auto_var, (int name ));
-_PROTOTYPE(void free_a_tree, (bc_array_node *root, int depth ));
-_PROTOTYPE(void pop_vars, (arg_list *list ));
-_PROTOTYPE(void process_params, (program_counter *pc, int func ));
-
-/* For the scanner and parser.... */
-_PROTOTYPE(int yyparse, (void));
-_PROTOTYPE(int yylex, (void));
-
-/* Other things... */
-_PROTOTYPE (int getopt, (int, char * CONST [], CONST char *));
-
diff --git a/gnu/usr.bin/bc/scan.l b/gnu/usr.bin/bc/scan.l
deleted file mode 100644
index 8189364..0000000
--- a/gnu/usr.bin/bc/scan.l
+++ /dev/null
@@ -1,196 +0,0 @@
-%{
-/* scan.l: the (f)lex description file for the scanner. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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 "y.tab.h"
-#include "global.h"
-#include "proto.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
-
-/* We want to define our own yywrap. */
-#undef yywrap
-_PROTOTYPE(int yywrap, (void));
-
-/* 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! */
-#include <errno.h>
-#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" );
-
-%}
-DIGIT [0-9A-F]
-LETTER [a-z]
-%%
-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);
-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(MUL_OP); }
-"="|\+=|-=|\*=|\/=|%=|\^= { 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/gnu/usr.bin/bc/storage.c b/gnu/usr.bin/bc/storage.c
deleted file mode 100644
index b4ed270..0000000
--- a/gnu/usr.bin/bc/storage.c
+++ /dev/null
@@ -1,963 +0,0 @@
-/* storage.c: Code and data storage manipulations. This includes labels. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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;
- 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 = 0;
-
- 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 = 0;
- char toobig;
-
- if (var_name > 2)
- {
- /* 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;
- }
- }
- 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;
- }
- }
-}
-
-
-/* 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;
-
- 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;
-
- 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);
- }
-}
-
-
-/* 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);
- }
- }
-}
-
-
-/* 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;
-
- 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);
-
- }
-}
-
-
-/* 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);
- }
- }
-}
-
-
-/* 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;
- }
-}
-
-
-/* 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];
- a_dest->a_param = TRUE;
- a_dest->a_value = 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/gnu/usr.bin/bc/util.c b/gnu/usr.bin/bc/util.c
deleted file mode 100644
index fe7315a..0000000
--- a/gnu/usr.bin/bc/util.c
+++ /dev/null
@@ -1,820 +0,0 @@
-/* util.c: Utility routines for bc. */
-
-/* This file is part of bc written for MINIX.
- Copyright (C) 1991, 1992, 1993, 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 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)
- arg_list *args;
- int val;
-{ arg_list *temp;
-
- temp = (arg_list *) bc_malloc (sizeof (arg_list));
- temp->av_name = val;
- 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+11);
- else
- {
- temp = (char *) bc_malloc (len);
- *temp = 0;
- return temp;
- }
-
- /* Add the current number to the end of the string. */
- 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->av_name < 0)
- warn ("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;
- }
- 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>". */
-
-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);
- }
-}
-
-
-/* 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;
- next_var = 4; /* 0 => ibase, 1 => obase, 2 => scale, 3 => last. */
-}
-
-
-/* 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);
- }
-
- return (0); /* NOT_REACHED */
-}
-
-
-/* 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 types 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 = g_argv[optind-1];
- 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 = g_argv[optind-1];
- 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 = g_argv[optind-1];
- 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/gnu/usr.bin/bc/version.h b/gnu/usr.bin/bc/version.h
deleted file mode 100644
index 6bf3ba3..0000000
--- a/gnu/usr.bin/bc/version.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#define BC_VERSION \
-"bc 1.03 (Nov 2, 1994)\nCopyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc."
-
OpenPOWER on IntegriCloud