From 98b3149ca15aa1b31005c8f0884883fc14920811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 8 Oct 2017 13:03:32 +0200 Subject: [PATCH] bc: use the outsourced build. * remove in-tree bc. --- Jamfile | 2 +- build/jam/images/definitions/minimum | 4 +- src/bin/Jamfile | 1 - src/bin/bc/COPYING | 340 ---- src/bin/bc/Jamfile | 5 - src/bin/bc/bc/Jamfile | 12 - src/bin/bc/bc/bc.c | 1886 --------------------- src/bin/bc/bc/bc.h | 42 - src/bin/bc/bc/bc.rdef | 11 - src/bin/bc/bc/bc.y | 654 -------- src/bin/bc/bc/bcdefs.h | 188 --- src/bin/bc/bc/const.h | 98 -- src/bin/bc/bc/execute.c | 788 --------- src/bin/bc/bc/fix-libmath_h | 9 - src/bin/bc/bc/global.c | 42 - src/bin/bc/bc/global.h | 154 -- src/bin/bc/bc/libmath.b | 287 ---- src/bin/bc/bc/libmath.h | 40 - src/bin/bc/bc/load.c | 351 ---- src/bin/bc/bc/main.c | 352 ---- src/bin/bc/bc/proto.h | 148 -- src/bin/bc/bc/sbc.y | 448 ----- src/bin/bc/bc/scan.c | 2259 -------------------------- src/bin/bc/bc/scan.l | 374 ----- src/bin/bc/bc/storage.c | 1067 ------------ src/bin/bc/bc/util.c | 873 ---------- src/bin/bc/config.h | 82 - src/bin/bc/dc/Jamfile | 12 - src/bin/bc/dc/array.c | 122 -- src/bin/bc/dc/dc-proto.h | 90 - src/bin/bc/dc/dc-regdef.h | 43 - src/bin/bc/dc/dc.c | 183 --- src/bin/bc/dc/dc.h | 82 - src/bin/bc/dc/dc.rdef | 11 - src/bin/bc/dc/eval.c | 682 -------- src/bin/bc/dc/misc.c | 179 -- src/bin/bc/dc/numeric.c | 600 ------- src/bin/bc/dc/stack.c | 494 ------ src/bin/bc/dc/string.c | 211 --- src/bin/bc/h/getopt.h | 133 -- src/bin/bc/h/number.h | 153 -- src/bin/bc/lib/Jamfile | 10 - src/bin/bc/lib/getopt.c | 752 --------- src/bin/bc/lib/getopt1.c | 184 --- src/bin/bc/lib/number.c | 1793 -------------------- src/bin/bc/lib/testmul.c | 244 --- src/bin/bc/lib/vfprintf.c | 31 - 47 files changed, 3 insertions(+), 16523 deletions(-) delete mode 100644 src/bin/bc/COPYING delete mode 100644 src/bin/bc/Jamfile delete mode 100644 src/bin/bc/bc/Jamfile delete mode 100644 src/bin/bc/bc/bc.c delete mode 100644 src/bin/bc/bc/bc.h delete mode 100644 src/bin/bc/bc/bc.rdef delete mode 100644 src/bin/bc/bc/bc.y delete mode 100644 src/bin/bc/bc/bcdefs.h delete mode 100644 src/bin/bc/bc/const.h delete mode 100644 src/bin/bc/bc/execute.c delete mode 100644 src/bin/bc/bc/fix-libmath_h delete mode 100644 src/bin/bc/bc/global.c delete mode 100644 src/bin/bc/bc/global.h delete mode 100644 src/bin/bc/bc/libmath.b delete mode 100644 src/bin/bc/bc/libmath.h delete mode 100644 src/bin/bc/bc/load.c delete mode 100644 src/bin/bc/bc/main.c delete mode 100644 src/bin/bc/bc/proto.h delete mode 100644 src/bin/bc/bc/sbc.y delete mode 100644 src/bin/bc/bc/scan.c delete mode 100644 src/bin/bc/bc/scan.l delete mode 100644 src/bin/bc/bc/storage.c delete mode 100644 src/bin/bc/bc/util.c delete mode 100644 src/bin/bc/config.h delete mode 100644 src/bin/bc/dc/Jamfile delete mode 100644 src/bin/bc/dc/array.c delete mode 100644 src/bin/bc/dc/dc-proto.h delete mode 100644 src/bin/bc/dc/dc-regdef.h delete mode 100644 src/bin/bc/dc/dc.c delete mode 100644 src/bin/bc/dc/dc.h delete mode 100644 src/bin/bc/dc/dc.rdef delete mode 100644 src/bin/bc/dc/eval.c delete mode 100644 src/bin/bc/dc/misc.c delete mode 100644 src/bin/bc/dc/numeric.c delete mode 100644 src/bin/bc/dc/stack.c delete mode 100644 src/bin/bc/dc/string.c delete mode 100644 src/bin/bc/h/getopt.h delete mode 100644 src/bin/bc/h/number.h delete mode 100644 src/bin/bc/lib/Jamfile delete mode 100644 src/bin/bc/lib/getopt.c delete mode 100644 src/bin/bc/lib/getopt1.c delete mode 100644 src/bin/bc/lib/number.c delete mode 100644 src/bin/bc/lib/testmul.c delete mode 100644 src/bin/bc/lib/vfprintf.c diff --git a/Jamfile b/Jamfile index c43f3765e1..b9acc0eb65 100644 --- a/Jamfile +++ b/Jamfile @@ -23,7 +23,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { # Include required packages: # primary architecture AddHaikuImagePackages [ FFilterByBuildFeatures - bash coreutils curl freetype icu libsolv zlib + bash bc coreutils curl freetype icu libsolv zlib regular_image @{ bzip2 ctags diffutils expat ffmpeg findutils gawk glu grep gutenprint diff --git a/build/jam/images/definitions/minimum b/build/jam/images/definitions/minimum index 77a32ae5f6..3f1e50f544 100644 --- a/build/jam/images/definitions/minimum +++ b/build/jam/images/definitions/minimum @@ -2,9 +2,9 @@ SYSTEM_BIN = [ FFilterByBuildFeatures addattr alert arp autologin - bc beep bfsinfo + beep bfsinfo catattr checkfs checkitout chop clear collectcatkeys compress copyattr - dc desklink df diskimage draggers + desklink df diskimage draggers driveinfo dstcheck dumpcatalog eject error fdinfo ffm filepanel finddir findpaths fortune fstrim diff --git a/src/bin/Jamfile b/src/bin/Jamfile index 517e6d71a9..d112cf666f 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -251,7 +251,6 @@ DoCatalogs filepanel ; SubInclude HAIKU_TOP src bin addattr ; -SubInclude HAIKU_TOP src bin bc ; SubInclude HAIKU_TOP src bin bfs_tools ; SubInclude HAIKU_TOP src bin cddb_lookup ; SubInclude HAIKU_TOP src bin compress ; diff --git a/src/bin/bc/COPYING b/src/bin/bc/COPYING deleted file mode 100644 index d60c31a97a..0000000000 --- a/src/bin/bc/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 - - 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. - - - Copyright (C) - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 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/src/bin/bc/Jamfile b/src/bin/bc/Jamfile deleted file mode 100644 index dd3d797554..0000000000 --- a/src/bin/bc/Jamfile +++ /dev/null @@ -1,5 +0,0 @@ -SubDir HAIKU_TOP src bin bc ; - -SubInclude HAIKU_TOP src bin bc lib ; -SubInclude HAIKU_TOP src bin bc bc ; -SubInclude HAIKU_TOP src bin bc dc ; diff --git a/src/bin/bc/bc/Jamfile b/src/bin/bc/bc/Jamfile deleted file mode 100644 index 00657e3447..0000000000 --- a/src/bin/bc/bc/Jamfile +++ /dev/null @@ -1,12 +0,0 @@ -SubDir HAIKU_TOP src bin bc bc ; - -SubDirCcFlags -DHAVE_CONFIG_H ; -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) lib ] ; -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) h ] ; - -BinCommand bc : - main.c bc.c scan.c execute.c load.c storage.c util.c global.c - : libbc.a - : bc.rdef ; - diff --git a/src/bin/bc/bc/bc.c b/src/bin/bc/bc/bc.c deleted file mode 100644 index 6750bb66d7..0000000000 --- a/src/bin/bc/bc/bc.c +++ /dev/null @@ -1,1886 +0,0 @@ - -/* A Bison parser, made from bc.y - by GNU Bison version 1.27 - */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define ENDOFLINE 257 -#define AND 258 -#define OR 259 -#define NOT 260 -#define STRING 261 -#define NAME 262 -#define NUMBER 263 -#define ASSIGN_OP 264 -#define REL_OP 265 -#define INCR_DECR 266 -#define Define 267 -#define Break 268 -#define Quit 269 -#define Length 270 -#define Return 271 -#define For 272 -#define If 273 -#define While 274 -#define Sqrt 275 -#define Else 276 -#define Scale 277 -#define Ibase 278 -#define Obase 279 -#define Auto 280 -#define Read 281 -#define Warranty 282 -#define Halt 283 -#define Last 284 -#define Continue 285 -#define Print 286 -#define Limits 287 -#define UNARY_MINUS 288 -#define HistoryVar 289 - -#line 1 "bc.y" - -/* bc.y: The grammar for a POSIX compatable bc processor with some - extensions to the language. */ - -/* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to: - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#include "bcdefs.h" -#include "global.h" -#include "proto.h" - -#line 40 "bc.y" -typedef union { - char *s_value; - char c_value; - int i_value; - arg_list *a_value; - } YYSTYPE; -#include - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif -#endif - - - -#define YYFINAL 185 -#define YYFLAG -32768 -#define YYNTBASE 50 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 289 ? yytranslate[x] : 84) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 40, 2, 2, 43, - 44, 38, 36, 47, 37, 2, 39, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 42, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 48, 2, 49, 41, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 45, 2, 46, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35 -}; - -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 1, 4, 7, 9, 12, 13, 15, 16, 18, - 22, 25, 26, 28, 31, 35, 38, 42, 44, 47, - 49, 51, 53, 55, 57, 59, 61, 63, 66, 67, - 68, 69, 70, 85, 86, 95, 96, 97, 106, 110, - 111, 115, 117, 121, 123, 125, 126, 127, 132, 133, - 146, 147, 149, 150, 154, 158, 160, 164, 169, 173, - 179, 186, 187, 189, 191, 195, 199, 205, 206, 208, - 209, 211, 212, 217, 218, 223, 224, 229, 232, 236, - 240, 244, 248, 252, 256, 260, 263, 265, 267, 271, - 276, 279, 282, 287, 292, 297, 301, 303, 308, 310, - 312, 314, 316, 318, 319, 321 -}; - -static const short yyrhs[] = { -1, - 50, 51, 0, 53, 3, 0, 69, 0, 1, 3, - 0, 0, 3, 0, 0, 55, 0, 53, 42, 55, - 0, 53, 42, 0, 0, 55, 0, 54, 3, 0, - 54, 3, 55, 0, 54, 42, 0, 54, 42, 56, - 0, 56, 0, 1, 56, 0, 28, 0, 33, 0, - 78, 0, 7, 0, 14, 0, 31, 0, 15, 0, - 29, 0, 17, 77, 0, 0, 0, 0, 0, 18, - 57, 43, 76, 42, 58, 76, 42, 59, 76, 44, - 60, 52, 56, 0, 0, 19, 43, 78, 44, 61, - 52, 56, 67, 0, 0, 0, 20, 62, 43, 78, - 63, 44, 52, 56, 0, 45, 54, 46, 0, 0, - 32, 64, 65, 0, 66, 0, 66, 47, 65, 0, - 7, 0, 78, 0, 0, 0, 22, 68, 52, 56, - 0, 0, 13, 8, 43, 71, 44, 52, 45, 83, - 72, 70, 54, 46, 0, 0, 73, 0, 0, 26, - 73, 3, 0, 26, 73, 42, 0, 8, 0, 8, - 48, 49, 0, 38, 8, 48, 49, 0, 73, 47, - 8, 0, 73, 47, 8, 48, 49, 0, 73, 47, - 38, 8, 48, 49, 0, 0, 75, 0, 78, 0, - 8, 48, 49, 0, 75, 47, 78, 0, 75, 47, - 8, 48, 49, 0, 0, 78, 0, 0, 78, 0, - 0, 82, 10, 79, 78, 0, 0, 78, 4, 80, - 78, 0, 0, 78, 5, 81, 78, 0, 6, 78, - 0, 78, 11, 78, 0, 78, 36, 78, 0, 78, - 37, 78, 0, 78, 38, 78, 0, 78, 39, 78, - 0, 78, 40, 78, 0, 78, 41, 78, 0, 37, - 78, 0, 82, 0, 9, 0, 43, 78, 44, 0, - 8, 43, 74, 44, 0, 12, 82, 0, 82, 12, - 0, 16, 43, 78, 44, 0, 21, 43, 78, 44, - 0, 23, 43, 78, 44, 0, 27, 43, 44, 0, - 8, 0, 8, 48, 78, 49, 0, 24, 0, 25, - 0, 23, 0, 35, 0, 30, 0, 0, 3, 0, - 83, 3, 0 -}; - -#endif - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 107, 116, 118, 120, 122, 128, 129, 132, 134, 135, - 136, 138, 140, 141, 142, 143, 144, 146, 147, 150, - 152, 154, 163, 170, 180, 191, 193, 195, 197, 202, - 212, 223, 233, 241, 248, 254, 260, 267, 273, 275, - 278, 279, 280, 282, 288, 291, 292, 300, 301, 315, - 321, 323, 325, 327, 329, 332, 334, 336, 338, 340, - 342, 345, 347, 349, 354, 360, 365, 381, 386, 388, - 393, 401, 413, 428, 436, 441, 449, 457, 463, 491, - 496, 501, 506, 511, 516, 521, 526, 535, 551, 553, - 569, 588, 611, 613, 615, 617, 623, 625, 630, 632, - 634, 636, 640, 647, 648, 649 -}; -#endif - - -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) - -static const char * const yytname[] = { "$","error","$undefined.","ENDOFLINE", -"AND","OR","NOT","STRING","NAME","NUMBER","ASSIGN_OP","REL_OP","INCR_DECR","Define", -"Break","Quit","Length","Return","For","If","While","Sqrt","Else","Scale","Ibase", -"Obase","Auto","Read","Warranty","Halt","Last","Continue","Print","Limits","UNARY_MINUS", -"HistoryVar","'+'","'-'","'*'","'/'","'%'","'^'","';'","'('","')'","'{'","'}'", -"','","'['","']'","program","input_item","opt_newline","semicolon_list","statement_list", -"statement_or_error","statement","@1","@2","@3","@4","@5","@6","@7","@8","print_list", -"print_element","opt_else","@9","function","@10","opt_parameter_list","opt_auto_define_list", -"define_list","opt_argument_list","argument_list","opt_expression","return_expression", -"expression","@11","@12","@13","named_expression","required_eol", NULL -}; -#endif - -static const short yyr1[] = { 0, - 50, 50, 51, 51, 51, 52, 52, 53, 53, 53, - 53, 54, 54, 54, 54, 54, 54, 55, 55, 56, - 56, 56, 56, 56, 56, 56, 56, 56, 57, 58, - 59, 60, 56, 61, 56, 62, 63, 56, 56, 64, - 56, 65, 65, 66, 66, 67, 68, 67, 70, 69, - 71, 71, 72, 72, 72, 73, 73, 73, 73, 73, - 73, 74, 74, 75, 75, 75, 75, 76, 76, 77, - 77, 79, 78, 80, 78, 81, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 82, 82, 82, 82, - 82, 82, 82, 83, 83, 83 -}; - -static const short yyr2[] = { 0, - 0, 2, 2, 1, 2, 0, 1, 0, 1, 3, - 2, 0, 1, 2, 3, 2, 3, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, - 0, 0, 14, 0, 8, 0, 0, 8, 3, 0, - 3, 1, 3, 1, 1, 0, 0, 4, 0, 12, - 0, 1, 0, 3, 3, 1, 3, 4, 3, 5, - 6, 0, 1, 1, 3, 3, 5, 0, 1, 0, - 1, 0, 4, 0, 4, 0, 4, 2, 3, 3, - 3, 3, 3, 3, 3, 2, 1, 1, 3, 4, - 2, 2, 4, 4, 4, 3, 1, 4, 1, 1, - 1, 1, 1, 0, 1, 2 -}; - -static const short yydefact[] = { 1, - 0, 0, 0, 23, 97, 88, 0, 0, 24, 26, - 0, 70, 29, 0, 36, 0, 101, 99, 100, 0, - 20, 27, 103, 25, 40, 21, 102, 0, 0, 0, - 2, 0, 9, 18, 4, 22, 87, 5, 19, 78, - 62, 0, 97, 101, 91, 0, 0, 28, 71, 0, - 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, - 13, 3, 0, 74, 76, 0, 0, 0, 0, 0, - 0, 0, 72, 92, 97, 0, 63, 64, 0, 51, - 0, 68, 0, 0, 0, 0, 96, 44, 41, 42, - 45, 89, 0, 16, 39, 10, 0, 0, 79, 80, - 81, 82, 83, 84, 85, 0, 0, 90, 0, 98, - 56, 0, 0, 52, 93, 0, 69, 34, 37, 94, - 95, 0, 15, 17, 75, 77, 73, 65, 97, 66, - 0, 0, 6, 0, 30, 6, 0, 43, 0, 57, - 0, 7, 0, 59, 0, 68, 0, 6, 67, 58, - 104, 0, 0, 0, 46, 0, 105, 53, 60, 0, - 31, 47, 35, 38, 106, 0, 49, 61, 68, 6, - 0, 0, 0, 0, 54, 55, 0, 32, 48, 50, - 6, 0, 33, 0, 0 -}; - -static const short yydefgoto[] = { 1, - 31, 143, 32, 60, 61, 34, 50, 146, 169, 181, - 136, 52, 137, 56, 89, 90, 163, 170, 35, 172, - 113, 167, 114, 76, 77, 116, 48, 36, 106, 97, - 98, 37, 158 -}; - -static const short yypact[] = {-32768, - 170, 375, 567,-32768, -25,-32768, -3, 7,-32768,-32768, - -32, 567,-32768, -29,-32768, -26, -7,-32768,-32768, -5, --32768,-32768,-32768,-32768,-32768,-32768,-32768, 567, 567, 213, --32768, 16,-32768,-32768,-32768, 642, 14,-32768,-32768, 63, - 597, 567, -9,-32768,-32768, 18, 567,-32768, 642, 19, - 567, 20, 567, 567, 15, 537,-32768, 122, 505, 3, --32768,-32768, 305,-32768,-32768, 567, 567, 567, 567, 567, - 567, 567,-32768,-32768, -18, 21, 26, 642, 39, -4, - 410, 567, 419, 567, 428, 466,-32768,-32768,-32768, 36, - 642,-32768, 259, 505,-32768,-32768, 567, 567, 404, 316, - 316, 44, 44, 44, 44, 567, 107,-32768, 627,-32768, - -8, 79, 45, 43,-32768, 49, 642,-32768, 642,-32768, --32768, 537,-32768,-32768, 63, 652, 404,-32768, 38, 642, - 46, 48, 90, -1,-32768, 90, 61,-32768, 337,-32768, - 59,-32768, 65, 64, 103, 567, 505, 90,-32768,-32768, - 111, 68, 70, 78, 99, 505,-32768, 5,-32768, 75, --32768,-32768,-32768,-32768,-32768, -4,-32768,-32768, 567, 90, - 13, 213, 81, 505,-32768,-32768, 6,-32768,-32768,-32768, - 90, 505,-32768, 129,-32768 -}; - -static const short yypgoto[] = {-32768, --32768, -135,-32768, -37, 1, -2,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768, 25,-32768,-32768,-32768,-32768,-32768, --32768,-32768, -30,-32768,-32768, -136,-32768, 0,-32768,-32768, --32768, 131,-32768 -}; - - -#define YYLAST 693 - - -static const short yytable[] = { 39, - 147, 33, 40, 111, 43, 93, 144, 165, 93, 154, - 47, 49, 156, 51, 46, 175, 53, 41, 62, 44, - 18, 19, 42, 73, 41, 74, 23, 57, 58, 107, - 166, 27, 173, 112, 174, 54, 145, 55, 42, 131, - 78, 79, 64, 65, 94, 182, 81, 94, 95, 66, - 83, 180, 85, 86, 176, 91, 39, 63, 87, 134, - 80, 82, 84, 96, 108, 99, 100, 101, 102, 103, - 104, 105, 109, 66, 67, 68, 69, 70, 71, 72, - 41, 117, 122, 119, 72, 139, 132, 110, 133, 134, - 135, 124, 142, 123, 140, 141, 125, 126, 67, 68, - 69, 70, 71, 72, 148, 127, 79, 150, 130, 151, - 153, 152, 3, 157, 5, 6, 159, 160, 7, 161, - 162, 91, 11, 168, 178, 64, 65, 16, 185, 17, - 18, 19, 66, 20, 177, 171, 23, 45, 79, 0, - 0, 27, 0, 28, 155, 117, 138, 0, 0, 29, - 0, 0, 0, 164, 0, 128, 0, 67, 68, 69, - 70, 71, 72, 0, 0, 92, 0, 0, 117, 184, - 2, 179, -8, 0, 0, 3, 4, 5, 6, 183, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 17, 18, 19, 0, 20, 21, 22, 23, - 24, 25, 26, 0, 27, 0, 28, 0, 0, 0, - 0, -8, 29, 59, 30, -12, 0, 0, 3, 4, - 5, 6, 0, 0, 7, 0, 9, 10, 11, 12, - 13, 14, 15, 16, 0, 17, 18, 19, 0, 20, - 21, 22, 23, 24, 25, 26, 0, 27, 0, 28, - 0, 0, 0, 0, -12, 29, 0, 30, -12, 59, - 0, -14, 0, 0, 3, 4, 5, 6, 0, 0, - 7, 0, 9, 10, 11, 12, 13, 14, 15, 16, - 0, 17, 18, 19, 0, 20, 21, 22, 23, 24, - 25, 26, 0, 27, 0, 28, 0, 0, 0, 0, - -14, 29, 0, 30, -14, 59, 0, -11, 0, 0, - 3, 4, 5, 6, 0, 0, 7, 0, 9, 10, - 11, 12, 13, 14, 15, 16, 0, 17, 18, 19, - 0, 20, 21, 22, 23, 24, 25, 26, 0, 27, - 0, 28, 3, 0, 5, 6, -11, 29, 7, 30, - 0, 0, 11, 69, 70, 71, 72, 16, 0, 17, - 18, 19, 0, 20, 0, 0, 23, 0, 0, 0, - 0, 27, 0, 28, 0, 0, 0, 38, 0, 29, - 3, 4, 5, 6, 0, 149, 7, 0, 9, 10, - 11, 12, 13, 14, 15, 16, 0, 17, 18, 19, - 0, 20, 21, 22, 23, 24, 25, 26, 0, 27, - 0, 28, 0, 64, 65, 0, 0, 29, 0, 30, - 66, 0, 64, 65, 0, 0, 0, 0, 0, 66, - 0, 64, 65, 0, 0, 0, 0, 0, 66, 67, - 68, 69, 70, 71, 72, 67, 68, 69, 70, 71, - 72, 0, 0, 115, 67, 68, 69, 70, 71, 72, - 0, 0, 118, 67, 68, 69, 70, 71, 72, 64, - 65, 120, 0, 0, 0, 0, 66, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 67, 68, 69, 70, 71, 72, 0, 0, 121, - 3, 4, 5, 6, 0, 0, 7, 0, 9, 10, - 11, 12, 13, 14, 15, 16, 0, 17, 18, 19, - 0, 20, 21, 22, 23, 24, 25, 26, 0, 27, - 0, 28, 3, 88, 5, 6, 0, 29, 7, 30, - 0, 0, 11, 0, 0, 0, 0, 16, 0, 17, - 18, 19, 0, 20, 0, 0, 23, 0, 0, 0, - 0, 27, 3, 28, 5, 6, 0, 0, 7, 29, - 0, 0, 11, 0, 0, 0, 0, 16, 0, 17, - 18, 19, 0, 20, 0, 0, 23, 0, 0, 0, - 0, 27, 3, 28, 75, 6, 0, 0, 7, 29, - 0, 0, 11, 0, 0, 0, 0, 16, 0, 17, - 18, 19, 0, 20, 0, 0, 23, 0, 0, 0, - 0, 27, 3, 28, 129, 6, 0, 0, 7, 29, - 0, 0, 11, 0, 0, 64, 65, 16, 0, 17, - 18, 19, 66, 20, 0, 64, 23, 0, 0, 0, - 0, 27, 66, 28, 0, 0, 0, 0, 0, 29, - 0, 0, 0, 0, 0, 0, 0, 67, 68, 69, - 70, 71, 72, 0, 0, 0, 0, 67, 68, 69, - 70, 71, 72 -}; - -static const short yycheck[] = { 2, - 136, 1, 3, 8, 8, 3, 8, 3, 3, 146, - 43, 12, 148, 43, 8, 3, 43, 43, 3, 23, - 24, 25, 48, 10, 43, 12, 30, 28, 29, 48, - 26, 35, 169, 38, 170, 43, 38, 43, 48, 48, - 41, 42, 4, 5, 42, 181, 47, 42, 46, 11, - 51, 46, 53, 54, 42, 56, 59, 42, 44, 47, - 43, 43, 43, 63, 44, 66, 67, 68, 69, 70, - 71, 72, 47, 11, 36, 37, 38, 39, 40, 41, - 43, 82, 47, 84, 41, 48, 8, 49, 44, 47, - 42, 94, 3, 93, 49, 48, 97, 98, 36, 37, - 38, 39, 40, 41, 44, 106, 107, 49, 109, 45, - 8, 48, 6, 3, 8, 9, 49, 48, 12, 42, - 22, 122, 16, 49, 44, 4, 5, 21, 0, 23, - 24, 25, 11, 27, 172, 166, 30, 7, 139, -1, - -1, 35, -1, 37, 147, 146, 122, -1, -1, 43, - -1, -1, -1, 156, -1, 49, -1, 36, 37, 38, - 39, 40, 41, -1, -1, 44, -1, -1, 169, 0, - 1, 174, 3, -1, -1, 6, 7, 8, 9, 182, - -1, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, -1, 23, 24, 25, -1, 27, 28, 29, 30, - 31, 32, 33, -1, 35, -1, 37, -1, -1, -1, - -1, 42, 43, 1, 45, 3, -1, -1, 6, 7, - 8, 9, -1, -1, 12, -1, 14, 15, 16, 17, - 18, 19, 20, 21, -1, 23, 24, 25, -1, 27, - 28, 29, 30, 31, 32, 33, -1, 35, -1, 37, - -1, -1, -1, -1, 42, 43, -1, 45, 46, 1, - -1, 3, -1, -1, 6, 7, 8, 9, -1, -1, - 12, -1, 14, 15, 16, 17, 18, 19, 20, 21, - -1, 23, 24, 25, -1, 27, 28, 29, 30, 31, - 32, 33, -1, 35, -1, 37, -1, -1, -1, -1, - 42, 43, -1, 45, 46, 1, -1, 3, -1, -1, - 6, 7, 8, 9, -1, -1, 12, -1, 14, 15, - 16, 17, 18, 19, 20, 21, -1, 23, 24, 25, - -1, 27, 28, 29, 30, 31, 32, 33, -1, 35, - -1, 37, 6, -1, 8, 9, 42, 43, 12, 45, - -1, -1, 16, 38, 39, 40, 41, 21, -1, 23, - 24, 25, -1, 27, -1, -1, 30, -1, -1, -1, - -1, 35, -1, 37, -1, -1, -1, 3, -1, 43, - 6, 7, 8, 9, -1, 49, 12, -1, 14, 15, - 16, 17, 18, 19, 20, 21, -1, 23, 24, 25, - -1, 27, 28, 29, 30, 31, 32, 33, -1, 35, - -1, 37, -1, 4, 5, -1, -1, 43, -1, 45, - 11, -1, 4, 5, -1, -1, -1, -1, -1, 11, - -1, 4, 5, -1, -1, -1, -1, -1, 11, 36, - 37, 38, 39, 40, 41, 36, 37, 38, 39, 40, - 41, -1, -1, 44, 36, 37, 38, 39, 40, 41, - -1, -1, 44, 36, 37, 38, 39, 40, 41, 4, - 5, 44, -1, -1, -1, -1, 11, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 36, 37, 38, 39, 40, 41, -1, -1, 44, - 6, 7, 8, 9, -1, -1, 12, -1, 14, 15, - 16, 17, 18, 19, 20, 21, -1, 23, 24, 25, - -1, 27, 28, 29, 30, 31, 32, 33, -1, 35, - -1, 37, 6, 7, 8, 9, -1, 43, 12, 45, - -1, -1, 16, -1, -1, -1, -1, 21, -1, 23, - 24, 25, -1, 27, -1, -1, 30, -1, -1, -1, - -1, 35, 6, 37, 8, 9, -1, -1, 12, 43, - -1, -1, 16, -1, -1, -1, -1, 21, -1, 23, - 24, 25, -1, 27, -1, -1, 30, -1, -1, -1, - -1, 35, 6, 37, 8, 9, -1, -1, 12, 43, - -1, -1, 16, -1, -1, -1, -1, 21, -1, 23, - 24, 25, -1, 27, -1, -1, 30, -1, -1, -1, - -1, 35, 6, 37, 8, 9, -1, -1, 12, 43, - -1, -1, 16, -1, -1, 4, 5, 21, -1, 23, - 24, 25, 11, 27, -1, 4, 30, -1, -1, -1, - -1, 35, 11, 37, -1, -1, -1, -1, -1, 43, - -1, -1, -1, -1, -1, -1, -1, 36, 37, 38, - 39, 40, 41, -1, -1, -1, -1, 36, 37, 38, - 39, 40, 41 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/gnu/share/bison.simple" -/* This file comes from bison-1.27. */ - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for malloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#include -#endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ -/* #include */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ -#endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC malloc -#endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, unsigned int count) -{ - register char *t = to; - register char *f = from; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 216 "/usr/gnu/share/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -#ifdef YYPARSE_PARAM -int yyparse (void *); -#else -int yyparse (void); -#endif -#endif - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 1: -#line 108 "bc.y" -{ - yyval.i_value = 0; - if (interactive && !quiet) - { - show_bc_version (); - welcome (); - } - ; - break;} -case 3: -#line 119 "bc.y" -{ run_code (); ; - break;} -case 4: -#line 121 "bc.y" -{ run_code (); ; - break;} -case 5: -#line 123 "bc.y" -{ - yyerrok; - init_gen (); - ; - break;} -case 7: -#line 130 "bc.y" -{ warn ("newline not allowed"); ; - break;} -case 8: -#line 133 "bc.y" -{ yyval.i_value = 0; ; - break;} -case 12: -#line 139 "bc.y" -{ yyval.i_value = 0; ; - break;} -case 19: -#line 148 "bc.y" -{ yyval.i_value = yyvsp[0].i_value; ; - break;} -case 20: -#line 151 "bc.y" -{ warranty (""); ; - break;} -case 21: -#line 153 "bc.y" -{ limits (); ; - break;} -case 22: -#line 155 "bc.y" -{ - if (yyvsp[0].i_value & 2) - warn ("comparison in expression"); - if (yyvsp[0].i_value & 1) - generate ("W"); - else - generate ("p"); - ; - break;} -case 23: -#line 164 "bc.y" -{ - yyval.i_value = 0; - generate ("w"); - generate (yyvsp[0].s_value); - free (yyvsp[0].s_value); - ; - break;} -case 24: -#line 171 "bc.y" -{ - if (break_label == 0) - yyerror ("Break outside a for/while"); - else - { - sprintf (genstr, "J%1d:", break_label); - generate (genstr); - } - ; - break;} -case 25: -#line 181 "bc.y" -{ - warn ("Continue statement"); - if (continue_label == 0) - yyerror ("Continue outside a for"); - else - { - sprintf (genstr, "J%1d:", continue_label); - generate (genstr); - } - ; - break;} -case 26: -#line 192 "bc.y" -{ exit (0); ; - break;} -case 27: -#line 194 "bc.y" -{ generate ("h"); ; - break;} -case 28: -#line 196 "bc.y" -{ generate ("R"); ; - break;} -case 29: -#line 198 "bc.y" -{ - yyvsp[0].i_value = break_label; - break_label = next_label++; - ; - break;} -case 30: -#line 203 "bc.y" -{ - if (yyvsp[-1].i_value & 2) - warn ("Comparison in first for expression"); - if (yyvsp[-1].i_value >= 0) - generate ("p"); - yyvsp[-1].i_value = next_label++; - sprintf (genstr, "N%1d:", yyvsp[-1].i_value); - generate (genstr); - ; - break;} -case 31: -#line 213 "bc.y" -{ - if (yyvsp[-1].i_value < 0) generate ("1"); - yyvsp[-1].i_value = next_label++; - sprintf (genstr, "B%1d:J%1d:", yyvsp[-1].i_value, break_label); - generate (genstr); - yyval.i_value = continue_label; - continue_label = next_label++; - sprintf (genstr, "N%1d:", continue_label); - generate (genstr); - ; - break;} -case 32: -#line 224 "bc.y" -{ - if (yyvsp[-1].i_value & 2 ) - warn ("Comparison in third for expression"); - if (yyvsp[-1].i_value & 16) - sprintf (genstr, "J%1d:N%1d:", yyvsp[-7].i_value, yyvsp[-4].i_value); - else - sprintf (genstr, "pJ%1d:N%1d:", yyvsp[-7].i_value, yyvsp[-4].i_value); - generate (genstr); - ; - break;} -case 33: -#line 234 "bc.y" -{ - sprintf (genstr, "J%1d:N%1d:", - continue_label, break_label); - generate (genstr); - break_label = yyvsp[-13].i_value; - continue_label = yyvsp[-5].i_value; - ; - break;} -case 34: -#line 242 "bc.y" -{ - yyvsp[-1].i_value = if_label; - if_label = next_label++; - sprintf (genstr, "Z%1d:", if_label); - generate (genstr); - ; - break;} -case 35: -#line 249 "bc.y" -{ - sprintf (genstr, "N%1d:", if_label); - generate (genstr); - if_label = yyvsp[-5].i_value; - ; - break;} -case 36: -#line 255 "bc.y" -{ - yyvsp[0].i_value = next_label++; - sprintf (genstr, "N%1d:", yyvsp[0].i_value); - generate (genstr); - ; - break;} -case 37: -#line 261 "bc.y" -{ - yyvsp[0].i_value = break_label; - break_label = next_label++; - sprintf (genstr, "Z%1d:", break_label); - generate (genstr); - ; - break;} -case 38: -#line 268 "bc.y" -{ - sprintf (genstr, "J%1d:N%1d:", yyvsp[-7].i_value, break_label); - generate (genstr); - break_label = yyvsp[-4].i_value; - ; - break;} -case 39: -#line 274 "bc.y" -{ yyval.i_value = 0; ; - break;} -case 40: -#line 276 "bc.y" -{ warn ("print statement"); ; - break;} -case 44: -#line 283 "bc.y" -{ - generate ("O"); - generate (yyvsp[0].s_value); - free (yyvsp[0].s_value); - ; - break;} -case 45: -#line 289 "bc.y" -{ generate ("P"); ; - break;} -case 47: -#line 293 "bc.y" -{ - warn ("else clause in if statement"); - yyvsp[0].i_value = next_label++; - sprintf (genstr, "J%d:N%1d:", yyvsp[0].i_value, if_label); - generate (genstr); - if_label = yyvsp[0].i_value; - ; - break;} -case 49: -#line 303 "bc.y" -{ - /* Check auto list against parameter list? */ - check_params (yyvsp[-5].a_value,yyvsp[0].a_value); - sprintf (genstr, "F%d,%s.%s[", - lookup(yyvsp[-7].s_value,FUNCTDEF), - arg_str (yyvsp[-5].a_value), arg_str (yyvsp[0].a_value)); - generate (genstr); - free_args (yyvsp[-5].a_value); - free_args (yyvsp[0].a_value); - yyvsp[-8].i_value = next_label; - next_label = 1; - ; - break;} -case 50: -#line 316 "bc.y" -{ - generate ("0R]"); - next_label = yyvsp[-11].i_value; - ; - break;} -case 51: -#line 322 "bc.y" -{ yyval.a_value = NULL; ; - break;} -case 53: -#line 326 "bc.y" -{ yyval.a_value = NULL; ; - break;} -case 54: -#line 328 "bc.y" -{ yyval.a_value = yyvsp[-1].a_value; ; - break;} -case 55: -#line 330 "bc.y" -{ yyval.a_value = yyvsp[-1].a_value; ; - break;} -case 56: -#line 333 "bc.y" -{ yyval.a_value = nextarg (NULL, lookup (yyvsp[0].s_value,SIMPLE), FALSE);; - break;} -case 57: -#line 335 "bc.y" -{ yyval.a_value = nextarg (NULL, lookup (yyvsp[-2].s_value,ARRAY), FALSE); ; - break;} -case 58: -#line 337 "bc.y" -{ yyval.a_value = nextarg (NULL, lookup (yyvsp[-2].s_value,ARRAY), TRUE); ; - break;} -case 59: -#line 339 "bc.y" -{ yyval.a_value = nextarg (yyvsp[-2].a_value, lookup (yyvsp[0].s_value,SIMPLE), FALSE); ; - break;} -case 60: -#line 341 "bc.y" -{ yyval.a_value = nextarg (yyvsp[-4].a_value, lookup (yyvsp[-2].s_value,ARRAY), FALSE); ; - break;} -case 61: -#line 343 "bc.y" -{ yyval.a_value = nextarg (yyvsp[-5].a_value, lookup (yyvsp[-2].s_value,ARRAY), TRUE); ; - break;} -case 62: -#line 346 "bc.y" -{ yyval.a_value = NULL; ; - break;} -case 64: -#line 350 "bc.y" -{ - if (yyvsp[0].i_value & 2) warn ("comparison in argument"); - yyval.a_value = nextarg (NULL,0,FALSE); - ; - break;} -case 65: -#line 355 "bc.y" -{ - sprintf (genstr, "K%d:", -lookup (yyvsp[-2].s_value,ARRAY)); - generate (genstr); - yyval.a_value = nextarg (NULL,1,FALSE); - ; - break;} -case 66: -#line 361 "bc.y" -{ - if (yyvsp[0].i_value & 2) warn ("comparison in argument"); - yyval.a_value = nextarg (yyvsp[-2].a_value,0,FALSE); - ; - break;} -case 67: -#line 366 "bc.y" -{ - sprintf (genstr, "K%d:", -lookup (yyvsp[-2].s_value,ARRAY)); - generate (genstr); - yyval.a_value = nextarg (yyvsp[-4].a_value,1,FALSE); - ; - break;} -case 68: -#line 382 "bc.y" -{ - yyval.i_value = 16; - warn ("Missing expression in for statement"); - ; - break;} -case 70: -#line 389 "bc.y" -{ - yyval.i_value = 0; - generate ("0"); - ; - break;} -case 71: -#line 394 "bc.y" -{ - if (yyvsp[0].i_value & 2) - warn ("comparison in return expresion"); - if (!(yyvsp[0].i_value & 4)) - warn ("return expression requires parenthesis"); - ; - break;} -case 72: -#line 402 "bc.y" -{ - if (yyvsp[0].c_value != '=') - { - if (yyvsp[-1].i_value < 0) - sprintf (genstr, "DL%d:", -yyvsp[-1].i_value); - else - sprintf (genstr, "l%d:", yyvsp[-1].i_value); - generate (genstr); - } - ; - break;} -case 73: -#line 413 "bc.y" -{ - if (yyvsp[0].i_value & 2) warn("comparison in assignment"); - if (yyvsp[-2].c_value != '=') - { - sprintf (genstr, "%c", yyvsp[-2].c_value); - generate (genstr); - } - if (yyvsp[-3].i_value < 0) - sprintf (genstr, "S%d:", -yyvsp[-3].i_value); - else - sprintf (genstr, "s%d:", yyvsp[-3].i_value); - generate (genstr); - yyval.i_value = 0; - ; - break;} -case 74: -#line 429 "bc.y" -{ - warn("&& operator"); - yyvsp[0].i_value = next_label++; - sprintf (genstr, "DZ%d:p", yyvsp[0].i_value); - generate (genstr); - ; - break;} -case 75: -#line 436 "bc.y" -{ - sprintf (genstr, "DZ%d:p1N%d:", yyvsp[-2].i_value, yyvsp[-2].i_value); - generate (genstr); - yyval.i_value = (yyvsp[-3].i_value | yyvsp[0].i_value) & ~4; - ; - break;} -case 76: -#line 442 "bc.y" -{ - warn("|| operator"); - yyvsp[0].i_value = next_label++; - sprintf (genstr, "B%d:", yyvsp[0].i_value); - generate (genstr); - ; - break;} -case 77: -#line 449 "bc.y" -{ - int tmplab; - tmplab = next_label++; - sprintf (genstr, "B%d:0J%d:N%d:1N%d:", - yyvsp[-2].i_value, tmplab, yyvsp[-2].i_value, tmplab); - generate (genstr); - yyval.i_value = (yyvsp[-3].i_value | yyvsp[0].i_value) & ~4; - ; - break;} -case 78: -#line 458 "bc.y" -{ - yyval.i_value = yyvsp[0].i_value & ~4; - warn("! operator"); - generate ("!"); - ; - break;} -case 79: -#line 464 "bc.y" -{ - yyval.i_value = 3; - switch (*(yyvsp[-1].s_value)) - { - case '=': - generate ("="); - break; - - case '!': - generate ("#"); - break; - - case '<': - if (yyvsp[-1].s_value[1] == '=') - generate ("{"); - else - generate ("<"); - break; - - case '>': - if (yyvsp[-1].s_value[1] == '=') - generate ("}"); - else - generate (">"); - break; - } - ; - break;} -case 80: -#line 492 "bc.y" -{ - generate ("+"); - yyval.i_value = (yyvsp[-2].i_value | yyvsp[0].i_value) & ~4; - ; - break;} -case 81: -#line 497 "bc.y" -{ - generate ("-"); - yyval.i_value = (yyvsp[-2].i_value | yyvsp[0].i_value) & ~4; - ; - break;} -case 82: -#line 502 "bc.y" -{ - generate ("*"); - yyval.i_value = (yyvsp[-2].i_value | yyvsp[0].i_value) & ~4; - ; - break;} -case 83: -#line 507 "bc.y" -{ - generate ("/"); - yyval.i_value = (yyvsp[-2].i_value | yyvsp[0].i_value) & ~4; - ; - break;} -case 84: -#line 512 "bc.y" -{ - generate ("%"); - yyval.i_value = (yyvsp[-2].i_value | yyvsp[0].i_value) & ~4; - ; - break;} -case 85: -#line 517 "bc.y" -{ - generate ("^"); - yyval.i_value = (yyvsp[-2].i_value | yyvsp[0].i_value) & ~4; - ; - break;} -case 86: -#line 522 "bc.y" -{ - generate ("n"); - yyval.i_value = yyvsp[0].i_value & ~4; - ; - break;} -case 87: -#line 527 "bc.y" -{ - yyval.i_value = 1; - if (yyvsp[0].i_value < 0) - sprintf (genstr, "L%d:", -yyvsp[0].i_value); - else - sprintf (genstr, "l%d:", yyvsp[0].i_value); - generate (genstr); - ; - break;} -case 88: -#line 536 "bc.y" -{ - int len = strlen(yyvsp[0].s_value); - yyval.i_value = 1; - if (len == 1 && *yyvsp[0].s_value == '0') - generate ("0"); - else if (len == 1 && *yyvsp[0].s_value == '1') - generate ("1"); - else - { - generate ("K"); - generate (yyvsp[0].s_value); - generate (":"); - } - free (yyvsp[0].s_value); - ; - break;} -case 89: -#line 552 "bc.y" -{ yyval.i_value = yyvsp[-1].i_value | 5; ; - break;} -case 90: -#line 554 "bc.y" -{ - yyval.i_value = 1; - if (yyvsp[-1].a_value != NULL) - { - sprintf (genstr, "C%d,%s:", - lookup (yyvsp[-3].s_value,FUNCT), - call_str (yyvsp[-1].a_value)); - free_args (yyvsp[-1].a_value); - } - else - { - sprintf (genstr, "C%d:", lookup (yyvsp[-3].s_value,FUNCT)); - } - generate (genstr); - ; - break;} -case 91: -#line 570 "bc.y" -{ - yyval.i_value = 1; - if (yyvsp[0].i_value < 0) - { - if (yyvsp[-1].c_value == '+') - sprintf (genstr, "DA%d:L%d:", -yyvsp[0].i_value, -yyvsp[0].i_value); - else - sprintf (genstr, "DM%d:L%d:", -yyvsp[0].i_value, -yyvsp[0].i_value); - } - else - { - if (yyvsp[-1].c_value == '+') - sprintf (genstr, "i%d:l%d:", yyvsp[0].i_value, yyvsp[0].i_value); - else - sprintf (genstr, "d%d:l%d:", yyvsp[0].i_value, yyvsp[0].i_value); - } - generate (genstr); - ; - break;} -case 92: -#line 589 "bc.y" -{ - yyval.i_value = 1; - if (yyvsp[-1].i_value < 0) - { - sprintf (genstr, "DL%d:x", -yyvsp[-1].i_value); - generate (genstr); - if (yyvsp[0].c_value == '+') - sprintf (genstr, "A%d:", -yyvsp[-1].i_value); - else - sprintf (genstr, "M%d:", -yyvsp[-1].i_value); - } - else - { - sprintf (genstr, "l%d:", yyvsp[-1].i_value); - generate (genstr); - if (yyvsp[0].c_value == '+') - sprintf (genstr, "i%d:", yyvsp[-1].i_value); - else - sprintf (genstr, "d%d:", yyvsp[-1].i_value); - } - generate (genstr); - ; - break;} -case 93: -#line 612 "bc.y" -{ generate ("cL"); yyval.i_value = 1;; - break;} -case 94: -#line 614 "bc.y" -{ generate ("cR"); yyval.i_value = 1;; - break;} -case 95: -#line 616 "bc.y" -{ generate ("cS"); yyval.i_value = 1;; - break;} -case 96: -#line 618 "bc.y" -{ - warn ("read function"); - generate ("cI"); yyval.i_value = 1; - ; - break;} -case 97: -#line 624 "bc.y" -{ yyval.i_value = lookup(yyvsp[0].s_value,SIMPLE); ; - break;} -case 98: -#line 626 "bc.y" -{ - if (yyvsp[-1].i_value > 1) warn("comparison in subscript"); - yyval.i_value = lookup(yyvsp[-3].s_value,ARRAY); - ; - break;} -case 99: -#line 631 "bc.y" -{ yyval.i_value = 0; ; - break;} -case 100: -#line 633 "bc.y" -{ yyval.i_value = 1; ; - break;} -case 101: -#line 635 "bc.y" -{ yyval.i_value = 2; ; - break;} -case 102: -#line 637 "bc.y" -{ yyval.i_value = 3; - warn ("History variable"); - ; - break;} -case 103: -#line 641 "bc.y" -{ yyval.i_value = 4; - warn ("Last variable"); - ; - break;} -case 104: -#line 647 "bc.y" -{ warn ("End of line required"); ; - break;} -case 106: -#line 650 "bc.y" -{ warn ("Too many end of lines"); ; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 542 "/usr/gnu/share/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 1; -} -#line 653 "bc.y" - - diff --git a/src/bin/bc/bc/bc.h b/src/bin/bc/bc/bc.h deleted file mode 100644 index 4a1f59eaf6..0000000000 --- a/src/bin/bc/bc/bc.h +++ /dev/null @@ -1,42 +0,0 @@ -typedef union { - char *s_value; - char c_value; - int i_value; - arg_list *a_value; - } YYSTYPE; -#define ENDOFLINE 257 -#define AND 258 -#define OR 259 -#define NOT 260 -#define STRING 261 -#define NAME 262 -#define NUMBER 263 -#define ASSIGN_OP 264 -#define REL_OP 265 -#define INCR_DECR 266 -#define Define 267 -#define Break 268 -#define Quit 269 -#define Length 270 -#define Return 271 -#define For 272 -#define If 273 -#define While 274 -#define Sqrt 275 -#define Else 276 -#define Scale 277 -#define Ibase 278 -#define Obase 279 -#define Auto 280 -#define Read 281 -#define Warranty 282 -#define Halt 283 -#define Last 284 -#define Continue 285 -#define Print 286 -#define Limits 287 -#define UNARY_MINUS 288 -#define HistoryVar 289 - - -extern YYSTYPE yylval; diff --git a/src/bin/bc/bc/bc.rdef b/src/bin/bc/bc/bc.rdef deleted file mode 100644 index 438cede357..0000000000 --- a/src/bin/bc/bc/bc.rdef +++ /dev/null @@ -1,11 +0,0 @@ -resource app_version -{ - major = 1, - middle = 0, - minor = 6, - variety = 5, - internal = 0, - short_info = "1.06", - long_info = "1.06 ©2000 The Free Software Foundation" -}; - diff --git a/src/bin/bc/bc/bc.y b/src/bin/bc/bc/bc.y deleted file mode 100644 index 403e326fc1..0000000000 --- a/src/bin/bc/bc/bc.y +++ /dev/null @@ -1,654 +0,0 @@ -%{ -/* bc.y: The grammar for a POSIX compatable bc processor with some - extensions to the language. */ - -/* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to: - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#include "bcdefs.h" -#include "global.h" -#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 grammar allows longer names. - Single letter names will still work. - b) Relational_expression allowed only one comparison. - This grammar has added boolean expressions with - && (and) || (or) and ! (not) and allowed all of them in - full expressions. - c) Added an else to the if. - d) Call by variable array parameters - e) read() procedure that reads a number under program control from stdin. - f) halt statement that halts the the program under program control. It - is an executed statement. - g) continue statement for for loops. - h) optional expressions in the for loop. - i) print statement to print multiple numbers per line. - j) warranty statement to print an extended warranty notice. - j) limits statement to print the processor's limits. -*/ - -%token ENDOFLINE AND OR NOT -%token STRING NAME NUMBER -/* '-', '+' are tokens themselves */ -/* '=', '+=', '-=', '*=', '/=', '%=', '^=' */ -%token ASSIGN_OP -/* '==', '<=', '>=', '!=', '<', '>' */ -%token REL_OP -/* '++', '--' */ -%token INCR_DECR -/* 'define', 'break', 'quit', 'length' */ -%token Define Break Quit Length -/* 'return', 'for', 'if', 'while', 'sqrt', 'else' */ -%token Return For If While Sqrt Else -/* 'scale', 'ibase', 'obase', 'auto', 'read' */ -%token Scale Ibase Obase Auto Read -/* 'warranty', 'halt', 'last', 'continue', 'print', 'limits' */ -%token Warranty, Halt, Last, Continue, Print, Limits -/* 'history' */ -%token UNARY_MINUS HistoryVar - -/* Types of all other things. */ -%type expression return_expression named_expression opt_expression -%type '+' '-' '*' '/' '%' -%type opt_parameter_list opt_auto_define_list define_list -%type opt_argument_list argument_list -%type program input_item semicolon_list statement_list -%type statement function statement_or_error required_eol - -/* precedence */ -%left OR -%left AND -%nonassoc NOT -%left REL_OP -%right ASSIGN_OP -%left '+' '-' -%left '*' '/' '%' -%right '^' -%nonassoc UNARY_MINUS -%nonassoc INCR_DECR - -%% -program : /* empty */ - { - $$ = 0; - if (interactive && !quiet) - { - show_bc_version (); - welcome (); - } - } - | program input_item - ; -input_item : semicolon_list ENDOFLINE - { run_code (); } - | function - { run_code (); } - | error ENDOFLINE - { - yyerrok; - init_gen (); - } - ; -opt_newline : /* empty */ - | ENDOFLINE - { warn ("newline not allowed"); } - ; -semicolon_list : /* empty */ - { $$ = 0; } - | statement_or_error - | semicolon_list ';' statement_or_error - | semicolon_list ';' - ; -statement_list : /* empty */ - { $$ = 0; } - | statement_or_error - | statement_list ENDOFLINE - | statement_list ENDOFLINE statement_or_error - | statement_list ';' - | statement_list ';' statement - ; -statement_or_error : statement - | error statement - { $$ = $2; } - ; -statement : Warranty - { warranty (""); } - | Limits - { limits (); } - | expression - { - if ($1 & 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 return_expression - { generate ("R"); } - | For - { - $1 = break_label; - break_label = next_label++; - } - '(' opt_expression ';' - { - if ($4 & 2) - warn ("Comparison in first for expression"); - if ($4 >= 0) - generate ("p"); - $4 = next_label++; - sprintf (genstr, "N%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); - $$ = continue_label; - continue_label = next_label++; - sprintf (genstr, "N%1d:", continue_label); - generate (genstr); - } - opt_expression ')' - { - if ($10 & 2 ) - warn ("Comparison in third for expression"); - if ($10 & 16) - sprintf (genstr, "J%1d:N%1d:", $4, $7); - else - sprintf (genstr, "pJ%1d:N%1d:", $4, $7); - generate (genstr); - } - opt_newline statement - { - sprintf (genstr, "J%1d:N%1d:", - continue_label, break_label); - generate (genstr); - break_label = $1; - continue_label = $9; - } - | If '(' expression ')' - { - $3 = if_label; - if_label = next_label++; - sprintf (genstr, "Z%1d:", if_label); - generate (genstr); - } - opt_newline statement opt_else - { - sprintf (genstr, "N%1d:", if_label); - generate (genstr); - if_label = $3; - } - | While - { - $1 = next_label++; - sprintf (genstr, "N%1d:", $1); - generate (genstr); - } - '(' expression - { - $4 = break_label; - break_label = next_label++; - sprintf (genstr, "Z%1d:", break_label); - generate (genstr); - } - ')' opt_newline statement - { - sprintf (genstr, "J%1d:N%1d:", $1, break_label); - generate (genstr); - break_label = $4; - } - | '{' statement_list '}' - { $$ = 0; } - | Print - { warn ("print statement"); } - print_list - ; -print_list : print_element - | print_element ',' print_list - ; -print_element : STRING - { - generate ("O"); - generate ($1); - free ($1); - } - | expression - { generate ("P"); } - ; -opt_else : /* nothing */ - | Else - { - warn ("else clause in if statement"); - $1 = next_label++; - sprintf (genstr, "J%d:N%1d:", $1, if_label); - generate (genstr); - if_label = $1; - } - opt_newline statement -function : Define NAME '(' opt_parameter_list ')' opt_newline - '{' required_eol opt_auto_define_list - { - /* Check auto list against parameter list? */ - check_params ($4,$9); - sprintf (genstr, "F%d,%s.%s[", - lookup($2,FUNCTDEF), - arg_str ($4), arg_str ($9)); - generate (genstr); - free_args ($4); - free_args ($9); - $1 = next_label; - next_label = 1; - } - statement_list /* ENDOFLINE */ '}' - { - generate ("0R]"); - next_label = $1; - } - ; -opt_parameter_list : /* empty */ - { $$ = NULL; } - | define_list - ; -opt_auto_define_list : /* empty */ - { $$ = NULL; } - | Auto define_list ENDOFLINE - { $$ = $2; } - | Auto define_list ';' - { $$ = $2; } - ; -define_list : NAME - { $$ = nextarg (NULL, lookup ($1,SIMPLE), FALSE);} - | NAME '[' ']' - { $$ = nextarg (NULL, lookup ($1,ARRAY), FALSE); } - | '*' NAME '[' ']' - { $$ = nextarg (NULL, lookup ($2,ARRAY), TRUE); } - | define_list ',' NAME - { $$ = nextarg ($1, lookup ($3,SIMPLE), FALSE); } - | define_list ',' NAME '[' ']' - { $$ = nextarg ($1, lookup ($3,ARRAY), FALSE); } - | define_list ',' '*' NAME '[' ']' - { $$ = nextarg ($1, lookup ($4,ARRAY), TRUE); } - ; -opt_argument_list : /* empty */ - { $$ = NULL; } - | argument_list - ; -argument_list : expression - { - if ($1 & 2) warn ("comparison in argument"); - $$ = nextarg (NULL,0,FALSE); - } - | NAME '[' ']' - { - sprintf (genstr, "K%d:", -lookup ($1,ARRAY)); - generate (genstr); - $$ = nextarg (NULL,1,FALSE); - } - | argument_list ',' expression - { - if ($3 & 2) warn ("comparison in argument"); - $$ = nextarg ($1,0,FALSE); - } - | argument_list ',' NAME '[' ']' - { - sprintf (genstr, "K%d:", -lookup ($3,ARRAY)); - generate (genstr); - $$ = nextarg ($1,1,FALSE); - } - ; - -/* Expression lval meanings! (Bits mean something!) - * 0 => Top op is assignment. - * 1 => Top op is not assignment. - * 2 => Comparison is somewhere in expression. - * 4 => Expression is in parenthesis. - * 16 => Empty optional expression. - */ - -opt_expression : /* empty */ - { - $$ = 16; - warn ("Missing expression in for statement"); - } - | expression - ; -return_expression : /* empty */ - { - $$ = 0; - generate ("0"); - } - | expression - { - if ($1 & 2) - warn ("comparison in return expresion"); - if (!($1 & 4)) - warn ("return expression requires parenthesis"); - } - ; -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 & 2) 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) & ~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) & ~4; - } - | NOT expression - { - $$ = $2 & ~4; - 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) & ~4; - } - | expression '-' expression - { - generate ("-"); - $$ = ($1 | $3) & ~4; - } - | expression '*' expression - { - generate ("*"); - $$ = ($1 | $3) & ~4; - } - | expression '/' expression - { - generate ("/"); - $$ = ($1 | $3) & ~4; - } - | expression '%' expression - { - generate ("%"); - $$ = ($1 | $3) & ~4; - } - | expression '^' expression - { - generate ("^"); - $$ = ($1 | $3) & ~4; - } - | '-' expression %prec UNARY_MINUS - { - generate ("n"); - $$ = $2 & ~4; - } - | 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 | 5; } - | 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; } - | HistoryVar - { $$ = 3; - warn ("History variable"); - } - | Last - { $$ = 4; - warn ("Last variable"); - } - ; - - -required_eol : { warn ("End of line required"); } - | ENDOFLINE - | required_eol ENDOFLINE - { warn ("Too many end of lines"); } - ; - -%% - diff --git a/src/bin/bc/bc/bcdefs.h b/src/bin/bc/bc/bcdefs.h deleted file mode 100644 index 260cd12384..0000000000 --- a/src/bin/bc/bc/bcdefs.h +++ /dev/null @@ -1,188 +0,0 @@ -/* bcdefs.h: The single file to include all constants and type definitions. */ - -/* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -/* Include the configuration file. */ -#include "config.h" - -/* Standard includes for all files. */ -#include -#include -#include -#ifdef HAVE_STRINGS_H -#include -#else -#include -#endif -#ifdef HAVE_LIMITS_H -#include -#endif - -#if defined(LIBEDIT) -#include -#endif - -#if defined(READLINE) -#include -#include -#endif - -/* Include the other definitions. */ -#include "const.h" -#include "number.h" - -/* These definitions define all the structures used in - code and data storage. This includes the representation of - labels. The "guiding" principle is to make structures that - take a minimum of space when unused but can be built to contain - the full structures. */ - -/* Labels are first. Labels are generated sequentially in functions - and full code. They just "point" to a single bye in the code. The - "address" is the byte number. The byte number is used to get an - actual character pointer. */ - -typedef struct bc_label_group - { - long l_adrs [ BC_LABEL_GROUP ]; - struct bc_label_group *l_next; - } bc_label_group; - -/* Argument list. Recorded in the function so arguments can - be checked at call time. */ - -typedef struct arg_list - { - int av_name; - int arg_is_var; /* Extension ... variable parameters. */ - struct arg_list *next; - } arg_list; - -/* Each function has its own code segments and labels. There can be - no jumps between functions so labels are unique to a function. */ - -typedef struct - { - char f_defined; /* Is this function defined yet. */ - char *f_body; - int f_body_size; /* Size of body. Power of 2. */ - int f_code_size; - bc_label_group *f_label; - arg_list *f_params; - arg_list *f_autos; - } bc_function; - -/* Code addresses. */ -typedef struct { - int pc_func; - int pc_addr; - } program_counter; - - -/* Variables are "pushable" (auto) and thus we need a stack mechanism. - This is built into the variable record. */ - -typedef struct bc_var - { - bc_num v_value; - struct bc_var *v_next; - } bc_var; - - -/* bc arrays can also be "auto" variables and thus need the same - kind of stacking mechanisms. */ - -typedef struct bc_array_node - { - union - { - bc_num n_num [NODE_SIZE]; - struct bc_array_node *n_down [NODE_SIZE]; - } n_items; - } bc_array_node; - -typedef struct bc_array - { - bc_array_node *a_tree; - short a_depth; - } bc_array; - -typedef struct bc_var_array - { - bc_array *a_value; - char a_param; - struct bc_var_array *a_next; - } bc_var_array; - - -/* For the stacks, execution and function, we need records to allow - for arbitrary size. */ - -typedef struct estack_rec { - bc_num s_num; - struct estack_rec *s_next; -} estack_rec; - -typedef struct fstack_rec { - int s_val; - struct fstack_rec *s_next; -} fstack_rec; - - -/* The following are for the name tree. */ - -typedef struct id_rec { - char *id; /* The program name. */ - /* A name == 0 => nothing assigned yet. */ - int a_name; /* The array variable name (number). */ - int f_name; /* The function name (number). */ - int v_name; /* The variable name (number). */ - short balance; /* For the balanced tree. */ - struct id_rec *left, *right; /* Tree pointers. */ -} id_rec; - - -/* A list of files to process. */ - -typedef struct file_node { - char *name; - struct file_node *next; -} file_node; - -/* Macro Definitions */ - -#if defined(LIBEDIT) -#define HISTORY_SIZE(n) history(hist, &histev, H_SETSIZE, n) -#define UNLIMIT_HISTORY history(hist, &histev, H_SETSIZE, INT_MAX) -#endif - -#if defined(READLINE) -#define HISTORY_SIZE(n) stifle_history(n) -#define UNLIMIT_HISTORY unstifle_history() -#endif diff --git a/src/bin/bc/bc/const.h b/src/bin/bc/bc/const.h deleted file mode 100644 index 1a7c5b82b0..0000000000 --- a/src/bin/bc/bc/const.h +++ /dev/null @@ -1,98 +0,0 @@ -/* const.h: Constants for bc. */ - -/* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - - -/* Define INT_MAX and LONG_MAX if not defined. Assuming 32 bits... */ - -#ifndef INT_MAX -#define INT_MAX 0x7FFFFFFF -#endif -#ifndef LONG_MAX -#define LONG_MAX 0x7FFFFFFF -#endif - - -/* Define constants in some reasonable size. The next 4 constants are - POSIX constants. */ - -#ifdef BC_BASE_MAX - /* on a POSIX.2 system may have defined these. Override. */ -# undef BC_BASE_MAX -# undef BC_SCALE_MAX -# undef BC_STRING_MAX -# undef BC_DIM_MAX -#endif - -#define BC_BASE_MAX INT_MAX -#define BC_SCALE_MAX INT_MAX -#define BC_STRING_MAX INT_MAX - - -/* Definitions for arrays. */ - -#define BC_DIM_MAX 65535 /* this should be NODE_SIZE^NODE_DEPTH-1 */ - -#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_START_SIZE 1024 /* Initial code body size. */ - -/* Maximum number of variables, arrays and functions and the - allocation increment for the dynamic arrays. */ - -#define MAX_STORE 32767 -#define STORE_INCR 32 - -/* Other interesting constants. */ - -#define FALSE 0 -#define TRUE 1 - -/* for use with lookup (). */ -#define SIMPLE 0 -#define ARRAY 1 -#define FUNCT 2 -#define FUNCTDEF 3 - -#define EXTERN extern -#ifdef __STDC__ -#define CONST const -#define VOID void -#else -#define CONST -#define VOID -#endif diff --git a/src/bin/bc/bc/execute.c b/src/bin/bc/bc/execute.c deleted file mode 100644 index d2864d1137..0000000000 --- a/src/bin/bc/bc/execute.c +++ /dev/null @@ -1,788 +0,0 @@ -/* execute.c - run a bc program. */ - -/* This file is part of GNU bc. - Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#include "bcdefs.h" -#include -#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; -{ - return (functions[pc->pc_func].f_body[pc->pc_addr++]); -} - - -/* The routine that actually runs the machine. */ - -void -execute () -{ - int label_num, l_gp, l_off; - bc_label_group *gp; - - char inst, ch; - int new_func; - int var_name; - - int const_base; - - bc_num temp_num; - arg_list *auto_list; - - /* Initialize this run... */ - pc.pc_func = 0; - pc.pc_addr = 0; - runtime_error = FALSE; - bc_init_num (&temp_num); - - /* Set up the interrupt mechanism for an interactive session. */ - if (interactive) - { - signal (SIGINT, stop_execution); - had_sigint = FALSE; - } - - while (pc.pc_addr < functions[pc.pc_func].f_code_size && !runtime_error) - { - inst = byte(&pc); - -#if DEBUG > 3 - { /* Print out address and the stack before each instruction.*/ - int depth; estack_rec *temp = ex_stack; - - printf ("func=%d addr=%d inst=%c\n",pc.pc_func, pc.pc_addr, inst); - if (temp == NULL) printf ("empty stack.\n", inst); - else - { - depth = 1; - while (temp != NULL) - { - printf (" %d = ", depth); - bc_out_num (temp->s_num, 10, out_char, std_only); - depth++; - temp = temp->s_next; - } - out_char ('\n'); - } - } -#endif - - switch ( inst ) - { - - case 'A' : /* increment array variable (Add one). */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name & 0x7f) << 8) + byte(&pc); - incr_array (var_name); - break; - - case 'B' : /* Branch to a label if TOS != 0. Remove value on TOS. */ - case 'Z' : /* Branch to a label if TOS == 0. Remove value on TOS. */ - c_code = !bc_is_zero (ex_stack->s_num); - pop (); - case 'J' : /* Jump to a label. */ - label_num = byte(&pc); /* Low order bits first. */ - label_num += byte(&pc) << 8; - if (inst == 'J' || (inst == 'B' && c_code) - || (inst == 'Z' && !c_code)) { - gp = functions[pc.pc_func].f_label; - l_gp = label_num >> BC_LABEL_LOG; - l_off = label_num % BC_LABEL_GROUP; - while (l_gp-- > 0) gp = gp->l_next; - pc.pc_addr = gp->l_adrs[l_off]; - } - break; - - case 'C' : /* Call a function. */ - /* Get the function number. */ - new_func = byte(&pc); - if ((new_func & 0x80) != 0) - new_func = ((new_func & 0x7f) << 8) + byte(&pc); - - /* Check to make sure it is defined. */ - if (!functions[new_func].f_defined) - { - rt_error ("Function %s not defined.", f_names[new_func]); - break; - } - - /* Check and push parameters. */ - process_params (&pc, new_func); - - /* Push auto variables. */ - for (auto_list = functions[new_func].f_autos; - auto_list != NULL; - auto_list = auto_list->next) - auto_var (auto_list->av_name); - - /* Push pc and ibase. */ - fpush (pc.pc_func); - fpush (pc.pc_addr); - fpush (i_base); - - /* Reset pc to start of function. */ - pc.pc_func = new_func; - pc.pc_addr = 0; - break; - - case 'D' : /* Duplicate top of stack */ - push_copy (ex_stack->s_num); - break; - - case 'K' : /* Push a constant */ - /* Get the input base and convert it to a bc number. */ - if (pc.pc_func == 0) - const_base = i_base; - else - const_base = fn_stack->s_val; - if (const_base == 10) - push_b10_const (&pc); - else - push_constant (prog_char, const_base); - break; - - case 'L' : /* load array variable */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name & 0x7f) << 8) + byte(&pc); - load_array (var_name); - break; - - case 'M' : /* decrement array variable (Minus!) */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name & 0x7f) << 8) + byte(&pc); - decr_array (var_name); - break; - - case 'O' : /* Write a string to the output with processing. */ - while ((ch = byte(&pc)) != '"') - if (ch != '\\') - out_schar (ch); - else - { - ch = byte(&pc); - if (ch == '"') break; - switch (ch) - { - case 'a': out_schar (007); break; - case 'b': out_schar ('\b'); break; - case 'f': out_schar ('\f'); break; - case 'n': out_schar ('\n'); break; - case 'q': out_schar ('"'); break; - case 'r': out_schar ('\r'); break; - case 't': out_schar ('\t'); break; - case '\\': out_schar ('\\'); break; - default: break; - } - } - fflush (stdout); - break; - - case 'R' : /* Return from function */ - if (pc.pc_func != 0) - { - /* "Pop" autos and parameters. */ - pop_vars(functions[pc.pc_func].f_autos); - pop_vars(functions[pc.pc_func].f_params); - /* reset the pc. */ - fpop (); - pc.pc_addr = fpop (); - pc.pc_func = fpop (); - } - else - rt_error ("Return from main program."); - break; - - case 'S' : /* store array variable */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name & 0x7f ) << 8) + byte(&pc); - store_array (var_name); - break; - - case 'T' : /* Test tos for zero */ - c_code = bc_is_zero (ex_stack->s_num); - assign (c_code); - break; - - case 'W' : /* Write the value on the top of the stack. */ - case 'P' : /* Write the value on the top of the stack. No newline. */ - bc_out_num (ex_stack->s_num, o_base, out_char, std_only); - if (inst == 'W') out_char ('\n'); - store_var (4); /* Special variable "last". */ - fflush (stdout); - pop (); - break; - - case 'c' : /* Call special function. */ - new_func = byte(&pc); - - switch (new_func) - { - case 'L': /* Length function. */ - /* For the number 0.xxxx, 0 is not significant. */ - if (ex_stack->s_num->n_len == 1 && - ex_stack->s_num->n_scale != 0 && - ex_stack->s_num->n_value[0] == 0 ) - bc_int2num (&ex_stack->s_num, ex_stack->s_num->n_scale); - else - bc_int2num (&ex_stack->s_num, ex_stack->s_num->n_len - + ex_stack->s_num->n_scale); - break; - - case 'S': /* Scale function. */ - bc_int2num (&ex_stack->s_num, ex_stack->s_num->n_scale); - break; - - case 'R': /* Square Root function. */ - if (!bc_sqrt (&ex_stack->s_num, scale)) - rt_error ("Square root of a negative number"); - break; - - case 'I': /* Read function. */ - push_constant (input_char, i_base); - break; - } - break; - - case 'd' : /* Decrement number */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name & 0x7f) << 8) + byte(&pc); - decr_var (var_name); - break; - - case 'h' : /* Halt the machine. */ - exit (0); - - case 'i' : /* increment number */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name & 0x7f) << 8) + byte(&pc); - incr_var (var_name); - break; - - case 'l' : /* load variable */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name & 0x7f) << 8) + byte(&pc); - load_var (var_name); - break; - - case 'n' : /* Negate top of stack. */ - bc_sub (_zero_, ex_stack->s_num, &ex_stack->s_num, 0); - break; - - case 'p' : /* Pop the execution stack. */ - pop (); - break; - - case 's' : /* store variable */ - var_name = byte(&pc); - if ((var_name & 0x80) != 0) - var_name = ((var_name & 0x7f) << 8) + byte(&pc); - store_var (var_name); - break; - - case 'w' : /* Write a string to the output. */ - while ((ch = byte(&pc)) != '"') out_schar (ch); - fflush (stdout); - break; - - case 'x' : /* Exchange Top of Stack with the one under the tos. */ - if (check_stack(2)) { - bc_num temp = ex_stack->s_num; - ex_stack->s_num = ex_stack->s_next->s_num; - ex_stack->s_next->s_num = temp; - } - break; - - case '0' : /* Load Constant 0. */ - push_copy (_zero_); - break; - - case '1' : /* Load Constant 0. */ - push_copy (_one_); - break; - - case '!' : /* Negate the boolean value on top of the stack. */ - c_code = bc_is_zero (ex_stack->s_num); - assign (c_code); - break; - - case '&' : /* compare greater than */ - if (check_stack(2)) - { - c_code = !bc_is_zero (ex_stack->s_next->s_num) - && !bc_is_zero (ex_stack->s_num); - pop (); - assign (c_code); - } - break; - - case '|' : /* compare greater than */ - if (check_stack(2)) - { - c_code = !bc_is_zero (ex_stack->s_next->s_num) - || !bc_is_zero (ex_stack->s_num); - pop (); - assign (c_code); - } - break; - - case '+' : /* add */ - if (check_stack(2)) - { - bc_add (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num, 0); - pop(); - pop(); - push_num (temp_num); - bc_init_num (&temp_num); - } - break; - - case '-' : /* subtract */ - if (check_stack(2)) - { - bc_sub (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num, 0); - pop(); - pop(); - push_num (temp_num); - bc_init_num (&temp_num); - } - break; - - case '*' : /* multiply */ - if (check_stack(2)) - { - bc_multiply (ex_stack->s_next->s_num, ex_stack->s_num, - &temp_num, scale); - pop(); - pop(); - push_num (temp_num); - bc_init_num (&temp_num); - } - break; - - case '/' : /* divide */ - if (check_stack(2)) - { - if (bc_divide (ex_stack->s_next->s_num, - ex_stack->s_num, &temp_num, scale) == 0) - { - pop(); - pop(); - push_num (temp_num); - bc_init_num (&temp_num); - } - else - rt_error ("Divide by zero"); - } - break; - - case '%' : /* remainder */ - if (check_stack(2)) - { - if (bc_is_zero (ex_stack->s_num)) - rt_error ("Modulo by zero"); - else - { - bc_modulo (ex_stack->s_next->s_num, - ex_stack->s_num, &temp_num, scale); - pop(); - pop(); - push_num (temp_num); - bc_init_num (&temp_num); - } - } - break; - - case '^' : /* raise */ - if (check_stack(2)) - { - bc_raise (ex_stack->s_next->s_num, - ex_stack->s_num, &temp_num, scale); - if (bc_is_zero (ex_stack->s_next->s_num) && bc_is_neg (ex_stack->s_num)) - rt_error ("divide by zero"); - pop(); - pop(); - push_num (temp_num); - bc_init_num (&temp_num); - } - break; - - case '=' : /* compare equal */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) == 0; - pop (); - assign (c_code); - } - break; - - case '#' : /* compare not equal */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) != 0; - pop (); - assign (c_code); - } - break; - - case '<' : /* compare less than */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) == -1; - pop (); - assign (c_code); - } - break; - - case '{' : /* compare less than or equal */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) <= 0; - pop (); - assign (c_code); - } - break; - - case '>' : /* compare greater than */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) == 1; - pop (); - assign (c_code); - } - break; - - case '}' : /* compare greater than or equal */ - if (check_stack(2)) - { - c_code = bc_compare (ex_stack->s_next->s_num, - ex_stack->s_num) >= 0; - pop (); - assign (c_code); - } - break; - - default : /* error! */ - rt_error ("bad instruction: inst=%c", inst); - } - } - - /* Clean up the function stack and pop all autos/parameters. */ - while (pc.pc_func != 0) - { - pop_vars(functions[pc.pc_func].f_autos); - pop_vars(functions[pc.pc_func].f_params); - fpop (); - pc.pc_addr = fpop (); - pc.pc_func = fpop (); - } - - /* Clean up the execution stack. */ - while (ex_stack != NULL) pop(); - - /* Clean up the interrupt stuff. */ - if (interactive) - { - signal (SIGINT, use_quit); - if (had_sigint) - printf ("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((int)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 */ - bc_init_num (&temp); - bc_init_num (&result); - bc_init_num (&mult); - build = bc_copy_num (_zero_); - negative = FALSE; - - /* The conversion base. */ - bc_int2num (&mult, conv_base); - - /* Get things ready. */ - in_ch = in_char(); - while (in_ch == ' ') - in_ch = in_char(); - - if (in_ch == '+') - in_ch = in_char(); - else - if (in_ch == '-') - { - negative = TRUE; - in_ch = in_char(); - } - - /* Check for the special case of a single digit. */ - if (in_ch < 16) - { - first_ch = in_ch; - in_ch = in_char(); - if (in_ch < 16 && first_ch >= conv_base) - first_ch = conv_base - 1; - bc_int2num (&build, (int) first_ch); - } - - /* Convert the integer part. */ - while (in_ch < 16) - { - if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1; - bc_multiply (build, mult, &result, 0); - bc_int2num (&temp, (int) in_ch); - bc_add (result, temp, &build, 0); - in_ch = in_char(); - } - if (in_ch == '.') - { - in_ch = in_char(); - if (in_ch >= conv_base) in_ch = conv_base-1; - bc_free_num (&result); - bc_free_num (&temp); - divisor = bc_copy_num (_one_); - result = bc_copy_num (_zero_); - digits = 0; - while (in_ch < 16) - { - bc_multiply (result, mult, &result, 0); - bc_int2num (&temp, (int) in_ch); - bc_add (result, temp, &result, 0); - bc_multiply (divisor, mult, &divisor, 0); - digits++; - in_ch = in_char(); - if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1; - } - bc_divide (result, divisor, &result, digits); - bc_add (build, result, &build, 0); - } - - /* Final work. */ - if (negative) - bc_sub (_zero_, build, &build, 0); - - push_num (build); - bc_free_num (&temp); - bc_free_num (&result); - bc_free_num (&mult); -} - - -/* When converting base 10 constants from the program, we use this - more efficient way to convert them to numbers. PC tells where - the constant starts and is expected to be advanced to after - the constant. */ - -void -push_b10_const (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) - { - bc_init_num (&build); - bc_int2num (&build, inchar); - push_num (build); - inchar = byte(pc); - return; - } - } - - /* Build the new number. */ - if (kdigits == 0) - { - build = bc_new_num (1,kscale); - ptr = build->n_value; - *ptr++ = 0; - } - else - { - build = bc_new_num (kdigits,kscale); - ptr = build->n_value; - } - - while (inchar != ':') - { - if (inchar != '.') - { - if (inchar > 9) - *ptr++ = 9; - else - *ptr++ = inchar; - } - inchar = byte(pc); - } - push_num (build); -} - - -/* Put the correct value on the stack for C_CODE. Frees TOS num. */ - -void -assign (c_code) - char c_code; -{ - bc_free_num (&ex_stack->s_num); - if (c_code) - ex_stack->s_num = bc_copy_num (_one_); - else - ex_stack->s_num = bc_copy_num (_zero_); -} - diff --git a/src/bin/bc/bc/fix-libmath_h b/src/bin/bc/bc/fix-libmath_h deleted file mode 100644 index f973a8c439..0000000000 --- a/src/bin/bc/bc/fix-libmath_h +++ /dev/null @@ -1,9 +0,0 @@ -ed libmath.h < 1) { - f += 1; - x /= 2; - scale += 1; - } - - /* Initialize the variables. */ - scale = n; - v = 1+x - a = x - d = 1 - - for (i=2; 1; i++) { - e = (a *= x) / (d *= i) - if (e == 0) { - if (f>0) while (f--) v = v*v; - scale = z - if (m) return (1/v); - return (v/1); - } - v += e - } -} - -/* Natural log. Uses the fact that ln(x^2) = 2*ln(x) - The series used is: - ln(x) = 2(a+a^3/3+a^5/5+...) where a=(x-1)/(x+1) -*/ - -define l(x) { - auto e, f, i, m, n, v, z - - /* return something for the special case. */ - if (x <= 0) return ((1 - 10^scale)/1) - - /* Precondition x to make .5 < x < 2.0. */ - z = scale; - scale = 6 + scale; - f = 2; - i=0 - while (x >= 2) { /* for large numbers */ - f *= 2; - x = sqrt(x); - } - while (x <= .5) { /* for small numbers */ - f *= 2; - x = sqrt(x); - } - - /* Set up the loop. */ - v = n = (x-1)/(x+1) - m = n*n - - /* Sum the series. */ - for (i=3; 1; i+=2) { - e = (n *= m) / i - if (e == 0) { - v = f*v - scale = z - return (v/1) - } - v += e - } -} - -/* Sin(x) uses the standard series: - sin(x) = x - x^3/3! + x^5/5! - x^7/7! ... */ - -define s(x) { - auto e, i, m, n, s, v, z - - /* precondition x. */ - z = scale - scale = 1.1*z + 2; - v = a(1) - if (x < 0) { - m = 1; - x = -x; - } - scale = 0 - n = (x / v + 2 )/4 - x = x - 4*n*v - if (n%2) x = -x - - /* Do the loop. */ - scale = z + 2; - v = e = x - s = -x*x - for (i=3; 1; i+=2) { - e *= s/(i*(i-1)) - if (e == 0) { - scale = z - if (m) return (-v/1); - return (v/1); - } - v += e - } -} - -/* Cosine : cos(x) = sin(x+pi/2) */ -define c(x) { - auto v, z; - z = scale; - scale = scale*1.2; - v = s(x+a(1)*2); - scale = z; - return (v/1); -} - -/* Arctan: Using the formula: - atan(x) = atan(c) + atan((x-c)/(1+xc)) for a small c (.2 here) - For under .2, use the series: - atan(x) = x - x^3/3 + x^5/5 - x^7/7 + ... */ - -define a(x) { - auto a, e, f, i, m, n, s, v, z - - /* a is the value of a(.2) if it is needed. */ - /* f is the value to multiply by a in the return. */ - /* e is the value of the current term in the series. */ - /* v is the accumulated value of the series. */ - /* m is 1 or -1 depending on x (-x -> -1). results are divided by m. */ - /* i is the denominator value for series element. */ - /* n is the numerator value for the series element. */ - /* s is -x*x. */ - /* z is the saved user's scale. */ - - /* Negative x? */ - m = 1; - if (x<0) { - m = -1; - x = -x; - } - - /* Special case and for fast answers */ - if (x==1) { - if (scale <= 25) return (.7853981633974483096156608/m) - if (scale <= 40) return (.7853981633974483096156608458198757210492/m) - if (scale <= 60) \ - return (.785398163397448309615660845819875721049292349843776455243736/m) - } - if (x==.2) { - if (scale <= 25) return (.1973955598498807583700497/m) - if (scale <= 40) return (.1973955598498807583700497651947902934475/m) - if (scale <= 60) \ - return (.197395559849880758370049765194790293447585103787852101517688/m) - } - - - /* Save the scale. */ - z = scale; - - /* Note: a and f are known to be zero due to being auto vars. */ - /* Calculate atan of a known number. */ - if (x > .2) { - scale = z+5; - a = a(.2); - } - - /* Precondition x. */ - scale = z+3; - while (x > .2) { - f += 1; - x = (x-.2) / (1+x*.2); - } - - /* Initialize the series. */ - v = n = x; - s = -x*x; - - /* Calculate the series. */ - for (i=3; 1; i+=2) { - e = (n *= s) / i; - if (e == 0) { - scale = z; - return ((f*a+v)/m); - } - v += e - } -} - - -/* Bessel function of integer order. Uses the following: - j(-n,x) = (-1)^n*j(n,x) - j(n,x) = x^n/(2^n*n!) * (1 - x^2/(2^2*1!*(n+1)) + x^4/(2^4*2!*(n+1)*(n+2)) - - x^6/(2^6*3!*(n+1)*(n+2)*(n+3)) .... ) -*/ -define j(n,x) { - auto a, b, d, e, f, i, m, s, v, z - - /* Make n an integer and check for negative n. */ - z = scale; - scale = 0; - n = n/1; - if (n<0) { - n = -n; - if (n%2 == 1) m = 1; - } - - /* save ibase */ - b = ibase; - ibase = A; - - /* Compute the factor of x^n/(2^n*n!) */ - f = 1; - for (i=2; i<=n; i++) f = f*i; - scale = 1.5*z; - f = x^n / 2^n / f; - - /* Initialize the loop .*/ - v = e = 1; - s = -x*x/4 - scale = 1.5*z + length(f) - scale(f); - - /* The Loop.... */ - for (i=1; 1; i++) { - e = e * s / i / (n+i); - if (e == 0) { - ibase = b; - scale = z - if (m) return (-f*v/1); - return (f*v/1); - } - v += e; - } -} diff --git a/src/bin/bc/bc/libmath.h b/src/bin/bc/bc/libmath.h deleted file mode 100644 index bf48f4b690..0000000000 --- a/src/bin/bc/bc/libmath.h +++ /dev/null @@ -1,40 +0,0 @@ -{"@iK20:s2:p@r", -"@iF1,5.6,7,8,9,10,11,12,13,14[l5:0Z3:l9:1+s9:pl5:K2:", -"/s5:pl2:1+s2:pJ2:N3:l12:s2:p1l5:+s13:pl5:s6:p1s7:pK2:s10:pN5:", -"1B6:J4:N7:l10:i10:pJ5:N6:l6:l5:*s6:l7:l10:*s7:/s8:pl8:0=Z8:l9:", -"0>Z9:N10:l9:d9:Z11:l13:l13:*s13:pJ10:N11:N9:l14:s2:pl11:Z12:1", -"l13:/RN12:l13:1/RN8:l13:l8:+s13:pJ7:N4:0R]@r", -"@iF2,5.8,9,10,11,12,13,14[l5:0{Z1:1K10:l2:^-1/RN1:l2:s14:pK6:", -"l2:+s2:pK2:s9:p0s10:pN2:l5:K2:}Z3:l9:K2:*s9:pl5:cRs5:pJ2:N3:N4:", -"l5:K.5:{Z5:l9:K2:*s9:pl5:cRs5:pJ4:N5:l5:1-l5:1+/s12:s13:pl12:", -"l12:*s11:pK3:s10:pN7:1B8:J6:N9:l10:K2:+s10:pJ7:N8:l12:l11:*s12:", -"l10:/s8:pl8:0=Z10:l9:l13:*s13:pl14:s2:pl13:1/RN10:l13:l8:+s13:", -"pJ9:N6:0R]@r", -"@iF3,5.8,10,11,12,15,13,14[l2:s14:pK1.1:l14:*K2:+s2:p1C4,0:s13:", -"pl5:0Z10:l14:K5:+s2:pK.2:C4,0:s6:pN10:", -"l14:K3:+s2:pN11:l5:K.2:>Z12:l9:1+s9:pl5:K.2:-1l5:K.2:*+/s5:pJ11:N12:", -"l5:s12:s13:pl5:nl5:*s15:pK3:s10:pN14:1B15:J13:N16:l10:K2:+s10:", -"pJ14:N15:l12:l15:*s12:l10:/s8:pl8:0=Z17:l14:s2:pl9:l6:*l13:+l11:", -"/RN17:l13:l8:+s13:pJ16:N13:0R]@r", -"@iF6,12,5.6,16,7,8,9,10,11,15,13,14[l2:s14:p0s2:pl12:1/s12:pl12:", -"0= f->f_body_size) - { - f->f_body_size *= 2; - new_body = (char *) bc_malloc (f->f_body_size); - memcpy(new_body, f->f_body, f->f_body_size/2); - free (f->f_body); - f->f_body = new_body; - } - - /* Store the byte. */ - f->f_body[pc] = byte; - f->f_code_size++; -} - - -/* Define a label LAB to be the current program counter. */ - -void -def_label (lab) - long lab; -{ - bc_label_group *temp; - int group, offset, func; - - /* Get things ready. */ - group = lab >> BC_LABEL_LOG; - offset = lab % BC_LABEL_GROUP; - func = load_adr.pc_func; - - /* Make sure there is at least one label group. */ - if (functions[func].f_label == NULL) - { - functions[func].f_label = - (bc_label_group *) bc_malloc (sizeof(bc_label_group)); - functions[func].f_label->l_next = NULL; - } - - /* Add the label group. */ - temp = functions[func].f_label; - while (group > 0) - { - if (temp->l_next == NULL) - { - temp->l_next = (bc_label_group *) bc_malloc (sizeof(bc_label_group)); - temp->l_next->l_next = NULL; - } - temp = temp->l_next; - group --; - } - - /* Define it! */ - temp->l_adrs [offset] = load_adr.pc_addr; -} - -/* Several instructions have integers in the code. They - are all known to be legal longs. So, no error code - is added. STR is the pointer to the load string and - must be moved to the last non-digit character. */ - -long -long_val (str) - char **str; -{ int val = 0; - char neg = FALSE; - - if (**str == '-') - { - neg = TRUE; - (*str)++; - } - while (isdigit((int)(**str))) - val = val*10 + *(*str)++ - '0'; - - if (neg) - return -val; - else - return val; -} - - -/* load_code loads the CODE into the machine. */ - -void -load_code (code) - char *code; -{ - char *str; - long ap_name; /* auto or parameter name. */ - long label_no; - long vaf_name; /* variable, array or function number. */ - long func; - program_counter save_adr; - - /* Initialize. */ - str = code; - - /* Scan the code. */ - while (*str != 0) - { - /* If there was an error, don't continue. */ - if (had_error) return; - - if (load_str) - { - if (*str == '"') load_str = FALSE; - addbyte (*str++); - } - else - if (load_const) - { - if (*str == '\n') - str++; - else - { - if (*str == ':') - { - load_const = FALSE; - addbyte (*str++); - } - else - if (*str == '.') - addbyte (*str++); - else - if (*str >= 'A') - addbyte (*str++ + 10 - 'A'); - else - addbyte (*str++ - '0'); - } - } - else - { - switch (*str) - { - - case '"': /* Starts a string. */ - load_str = TRUE; - break; - - case 'N': /* A label */ - str++; - label_no = long_val (&str); - def_label (label_no); - break; - - case 'B': /* Branch to label. */ - case 'J': /* Jump to label. */ - case 'Z': /* Branch Zero to label. */ - addbyte(*str++); - label_no = long_val (&str); - if (label_no > 65535L) - { /* Better message? */ - fprintf (stderr,"Program too big.\n"); - exit(1); - } - addbyte ( (char) (label_no & 0xFF)); - addbyte ( (char) (label_no >> 8)); - break; - - case 'F': /* A function, get the name and initialize it. */ - str++; - func = long_val (&str); - clear_func (func); -#if DEBUG > 2 - printf ("Loading function number %d\n", func); -#endif - /* get the parameters */ - while (*str++ != '.') - { - if (*str == '.') - { - str++; - break; - } - if (*str == '*') - { - str++; - ap_name = long_val (&str); -#if DEBUG > 2 - printf ("var parameter number %d\n", ap_name); -#endif - functions[(int)func].f_params = - nextarg (functions[(int)func].f_params, ap_name, - TRUE); - } - else - { - ap_name = long_val (&str); -#if DEBUG > 2 - printf ("parameter number %d\n", ap_name); -#endif - functions[(int)func].f_params = - nextarg (functions[(int)func].f_params, ap_name, - FALSE); - } - } - - /* get the auto vars */ - while (*str != '[') - { - if (*str == ',') str++; - ap_name = long_val (&str); -#if DEBUG > 2 - printf ("auto number %d\n", ap_name); -#endif - functions[(int)func].f_autos = - nextarg (functions[(int)func].f_autos, ap_name, FALSE); - } - save_adr = load_adr; - load_adr.pc_func = func; - load_adr.pc_addr = 0; - break; - - case ']': /* A function end */ - functions[load_adr.pc_func].f_defined = TRUE; - load_adr = save_adr; - break; - - case 'C': /* Call a function. */ - addbyte (*str++); - func = long_val (&str); - if (func < 128) - addbyte ( (char) func); - else - { - addbyte (((func >> 8) & 0xff) | 0x80); - addbyte (func & 0xff); - } - if (*str == ',') str++; - while (*str != ':') - addbyte (*str++); - addbyte (':'); - break; - - case 'c': /* Call a special function. */ - addbyte (*str++); - addbyte (*str); - break; - - case 'K': /* A constant.... may have an "F" in it. */ - addbyte (*str); - load_const = TRUE; - break; - - case 'd': /* Decrement. */ - case 'i': /* Increment. */ - case 'l': /* Load. */ - case 's': /* Store. */ - case 'A': /* Array Increment */ - case 'M': /* Array Decrement */ - case 'L': /* Array Load */ - case 'S': /* Array Store */ - addbyte (*str++); - vaf_name = long_val (&str); - if (vaf_name < 128) - addbyte (vaf_name); - else - { - addbyte (((vaf_name >> 8) & 0xff) | 0x80); - addbyte (vaf_name & 0xff); - } - break; - - case '@': /* A command! */ - switch (*(++str)) - { - case 'i': - init_load (); - break; - case 'r': - execute (); - break; - } - break; - - case '\n': /* Ignore the newlines */ - break; - - default: /* Anything else */ - addbyte (*str); - } - str++; - } - } -} diff --git a/src/bin/bc/bc/main.c b/src/bin/bc/bc/main.c deleted file mode 100644 index 1b9f6d223c..0000000000 --- a/src/bin/bc/bc/main.c +++ /dev/null @@ -1,352 +0,0 @@ -/* main.c: The main program for bc. */ - -/* This file is part of GNU bc. - Copyright (C) 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#include "bcdefs.h" -#include -#include "global.h" -#include "proto.h" -#include "getopt.h" - - -/* Variables for processing multiple files. */ -static char first_file; - -/* Points to the last node in the file name list for easy adding. */ -static file_node *last = NULL; - -/* long option support */ -static struct option long_options[] = -{ - {"compile", 0, &compile_only, TRUE}, - {"help", 0, 0, 'h'}, - {"interactive", 0, 0, 'i'}, - {"mathlib", 0, &use_math, TRUE}, - {"quiet", 0, &quiet, TRUE}, - {"standard", 0, &std_only, TRUE}, - {"version", 0, 0, 'v'}, - {"warn", 0, &warn_not_std, TRUE}, - - {0, 0, 0, 0} -}; - - -void -usage (char *progname) -{ - printf ("usage: %s [options] [file ...]\n%s%s%s%s%s%s%s", progname, - " -h --help print this usage and exit\n", - " -i --interactive force interactive mode\n", - " -l --mathlib use the predefine math routnes\n", - " -q --quiet don't print initial banner\n", - " -s --standard non-standard bc constructs are errors\n", - " -w --warn warn about non-standard bc constructs\n", - " -v --version print version information and exit\n"); -} - - -void -parse_args (argc, argv) - int argc; - char **argv; -{ - int optch; - int long_index; - file_node *temp; - - /* Force getopt to initialize. Depends on GNU getopt. */ - optind = 0; - - /* Parse the command line */ - while (1) - { - optch = getopt_long (argc, argv, "chilqswv", long_options, &long_index); - - if (optch == EOF) /* End of arguments. */ - break; - - switch (optch) - { - case 'c': /* compile only */ - compile_only = TRUE; - break; - - case 'h': /* help */ - usage(argv[0]); - exit (0); - break; - - case 'i': /* force interactive */ - interactive = TRUE; - break; - - case 'l': /* math lib */ - use_math = TRUE; - break; - - case 'q': /* quiet mode */ - quiet = TRUE; - break; - - case 's': /* Non standard features give errors. */ - std_only = TRUE; - break; - - case 'v': /* Print the version. */ - show_bc_version (); - exit (0); - break; - - case 'w': /* Non standard features give warnings. */ - warn_not_std = TRUE; - break; - - default: - usage(argv[0]); - exit (1); - } - } - - /* Add file names to a list of files to process. */ - while (optind < argc) - { - temp = (file_node *) bc_malloc(sizeof(file_node)); - temp->name = argv[optind]; - temp->next = NULL; - if (last == NULL) - file_names = temp; - else - last->next = temp; - last = temp; - optind++; - } -} - -/* The main program for bc. */ -int -main (argc, argv) - int argc; - char *argv[]; -{ - char *env_value; - char *env_argv[30]; - int env_argc; - - /* Initialize many variables. */ - compile_only = FALSE; - use_math = FALSE; - warn_not_std = FALSE; - std_only = FALSE; - if (isatty(0) && isatty(1)) - interactive = TRUE; - else - interactive = FALSE; - quiet = FALSE; - file_names = NULL; - -#ifdef HAVE_SETVBUF - /* attempt to simplify interaction with applications such as emacs */ - (void) setvbuf(stdout, NULL, _IOLBF, 0); -#endif - - /* Environment arguments. */ - env_value = getenv ("BC_ENV_ARGS"); - if (env_value != NULL) - { - env_argc = 1; - env_argv[0] = "BC_ENV_ARGS"; - while (*env_value != 0) - { - if (*env_value != ' ') - { - env_argv[env_argc++] = env_value; - while (*env_value != ' ' && *env_value != 0) - env_value++; - if (*env_value != 0) - { - *env_value = 0; - env_value++; - } - } - else - env_value++; - } - parse_args (env_argc, env_argv); - } - - /* Command line arguments. */ - parse_args (argc, argv); - - /* Other environment processing. */ - if (getenv ("POSIXLY_CORRECT") != NULL) - std_only = TRUE; - - env_value = getenv ("BC_LINE_LENGTH"); - if (env_value != NULL) - { - line_size = atoi (env_value); - if (line_size < 2) - line_size = 70; - } - else - line_size = 70; - - /* Initialize the machine. */ - init_storage(); - init_load(); - - /* Set up interrupts to print a message. */ - if (interactive) - signal (SIGINT, use_quit); - - /* Initialize the front end. */ - init_tree(); - init_gen (); - is_std_in = FALSE; - first_file = TRUE; - if (!open_new_file ()) - exit (1); - -#if defined(LIBEDIT) - if (interactive) { - /* Enable libedit support. */ - edit = el_init ("bc", stdin, stdout, stderr); - hist = history_init(); - el_set (edit, EL_EDITOR, "emacs"); - el_set (edit, EL_HIST, history, hist); - el_set (edit, EL_PROMPT, null_prompt); - el_source (edit, NULL); - history (hist, &histev, H_SETSIZE, INT_MAX); - } -#endif - -#if defined(READLINE) - if (interactive) { - /* Readline support. Set both application name and input file. */ - rl_readline_name = "bc"; - rl_instream = stdin; - using_history (); - } -#endif - - /* Do the parse. */ - yyparse (); - - /* End the compile only output with a newline. */ - if (compile_only) - printf ("\n"); - - exit (0); -} - - -/* This is the function that opens all the files. - It returns TRUE if the file was opened, otherwise - it returns FALSE. */ - -int -open_new_file () -{ - FILE *new_file; - file_node *temp; - - /* Set the line number. */ - line_no = 1; - - /* Check to see if we are done. */ - if (is_std_in) return (FALSE); - - /* Open the other files. */ - if (use_math && first_file) - { - /* Load the code from a precompiled version of the math libarary. */ - extern char *libmath[]; - char **mstr; - char tmp; - /* These MUST be in the order of first mention of each function. - That is why "a" comes before "c" even though "a" is defined after - after "c". "a" is used in "s"! */ - tmp = lookup ("e", FUNCT); - tmp = lookup ("l", FUNCT); - tmp = lookup ("s", FUNCT); - tmp = lookup ("a", FUNCT); - tmp = lookup ("c", FUNCT); - tmp = lookup ("j", FUNCT); - mstr = libmath; - while (*mstr) { - load_code (*mstr); - mstr++; - } - } - - /* One of the argv values. */ - if (file_names != NULL) - { - new_file = fopen (file_names->name, "r"); - if (new_file != NULL) - { - new_yy_file (new_file); - temp = file_names; - file_name = temp->name; - file_names = temp->next; - free (temp); - return TRUE; - } - fprintf (stderr, "File %s is unavailable.\n", file_names->name); - exit (1); - } - - /* If we fall through to here, we should return stdin. */ - new_yy_file (stdin); - is_std_in = TRUE; - return TRUE; -} - - -/* Set yyin to the new file. */ - -void -new_yy_file (file) - FILE *file; -{ - if (!first_file) fclose (yyin); - yyin = file; - first_file = FALSE; -} - - -/* Message to use quit. */ - -void -use_quit (sig) - int sig; -{ - printf ("\n(interrupt) use quit to exit.\n"); - signal (SIGINT, use_quit); -} diff --git a/src/bin/bc/bc/proto.h b/src/bin/bc/bc/proto.h deleted file mode 100644 index 1e7311fc84..0000000000 --- a/src/bin/bc/bc/proto.h +++ /dev/null @@ -1,148 +0,0 @@ -/* proto.h: Prototype function definitions for "external" functions. */ - -/* This file is part of GNU bc. - Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -/* For the pc version using k&r ACK. (minix1.5 and earlier.) */ -#ifdef SHORTNAMES -#define init_numbers i_numbers -#define push_constant push__constant -#define load_const in_load_const -#define yy_get_next_buffer yyget_next_buffer -#define yy_init_buffer yyinit_buffer -#define yy_last_accepting_state yylast_accepting_state -#define arglist1 arg1list -#endif - -/* Include the standard library header files. */ -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif - -/* Define the _PROTOTYPE macro if it is needed. */ - -#ifndef _PROTOTYPE -#ifdef __STDC__ -#define _PROTOTYPE(func, args) func args -#else -#define _PROTOTYPE(func, args) func() -#endif -#endif - -/* From execute.c */ -_PROTOTYPE(void stop_execution, (int)); -_PROTOTYPE(unsigned char byte, (program_counter *pc)); -_PROTOTYPE(void execute, (void)); -_PROTOTYPE(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, int is_var)); -_PROTOTYPE(char *arg_str, (arg_list *args)); -_PROTOTYPE(char *call_str, (arg_list *args)); -_PROTOTYPE(void free_args, (arg_list *args)); -_PROTOTYPE(void check_params, (arg_list *params, arg_list *autos)); -_PROTOTYPE(void init_gen, (void)); -_PROTOTYPE(void generate, (char *str)); -_PROTOTYPE(void run_code, (void)); -_PROTOTYPE(void out_char, (int ch)); -_PROTOTYPE(void out_schar, (int ch)); -_PROTOTYPE(id_rec *find_id, (id_rec *tree, 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 show_bc_version, (void)); -_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 open_new_file, (void)); -_PROTOTYPE(void new_yy_file, (FILE *file)); -_PROTOTYPE(void use_quit, (int)); - -/* From storage.c */ -_PROTOTYPE(void init_storage, (void)); -_PROTOTYPE(void more_functions, (void)); -_PROTOTYPE(void more_variables, (void)); -_PROTOTYPE(void more_arrays, (void)); -_PROTOTYPE(void clear_func, (int func )); -_PROTOTYPE(int fpop, (void)); -_PROTOTYPE(void fpush, (int val )); -_PROTOTYPE(void pop, (void)); -_PROTOTYPE(void push_copy, (bc_num num )); -_PROTOTYPE(void push_num, (bc_num num )); -_PROTOTYPE(char check_stack, (int depth )); -_PROTOTYPE(bc_var *get_var, (int var_name )); -_PROTOTYPE(bc_num *get_array_num, (int var_index, long index )); -_PROTOTYPE(void store_var, (int var_name )); -_PROTOTYPE(void store_array, (int var_name )); -_PROTOTYPE(void load_var, (int var_name )); -_PROTOTYPE(void load_array, (int var_name )); -_PROTOTYPE(void decr_var, (int var_name )); -_PROTOTYPE(void decr_array, (int var_name )); -_PROTOTYPE(void incr_var, (int var_name )); -_PROTOTYPE(void incr_array, (int var_name )); -_PROTOTYPE(void auto_var, (int name )); -_PROTOTYPE(void free_a_tree, (bc_array_node *root, int depth )); -_PROTOTYPE(void pop_vars, (arg_list *list )); -_PROTOTYPE(void process_params, (program_counter *pc, int func )); - -/* For the scanner and parser.... */ -_PROTOTYPE(int yyparse, (void)); -_PROTOTYPE(int yylex, (void)); - -#if defined(LIBEDIT) -/* The *?*&^ prompt function */ -_PROTOTYPE(char *null_prompt, (EditLine *)); -#endif - -/* Other things... */ -#ifndef HAVE_UNISTD_H -_PROTOTYPE (int getopt, (int, char *[], CONST char *)); -#endif diff --git a/src/bin/bc/bc/sbc.y b/src/bin/bc/bc/sbc.y deleted file mode 100644 index b1ff1d143a..0000000000 --- a/src/bin/bc/bc/sbc.y +++ /dev/null @@ -1,448 +0,0 @@ -%{ -/* sbc.y: A POSIX bc processor written for minix with no extensions. */ - -/* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#include "bcdefs.h" -#include "global.h" /* To get the global variables. */ -#include "proto.h" -%} - -%start program - -%union { - char *s_value; - char c_value; - int i_value; - arg_list *a_value; - } - -%token ENDOFLINE AND OR NOT -%token STRING NAME NUMBER -/* '-', '+' are tokens themselves */ -%token ASSIGN_OP -/* '=', '+=', '-=', '*=', '/=', '%=', '^=' */ -%token REL_OP -/* '==', '<=', '>=', '!=', '<', '>' */ -%token INCR_DECR -/* '++', '--' */ -%token Define Break Quit Length -/* 'define', 'break', 'quit', 'length' */ -%token Return For If While Sqrt Else -/* 'return', 'for', 'if', 'while', 'sqrt', 'else' */ -%token Scale Ibase Obase Auto Read -/* 'scale', 'ibase', 'obase', 'auto', 'read' */ -%token Warranty, Halt, Last, Continue, Print, Limits -/* 'warranty', 'halt', 'last', 'continue', 'print', 'limits' */ - -/* The types of all other non-terminals. */ -%type expression named_expression return_expression -%type opt_parameter_list parameter_list opt_auto_define_list -%type define_list opt_argument_list argument_list -%type program input_item semicolon_list statement_list -%type statement_or_error statement function relational_expression - -/* precedence */ -%nonassoc REL_OP -%right ASSIGN_OP -%left '+' '-' -%left '*' '/' '%' -%right '^' -%nonassoc UNARY_MINUS -%nonassoc INCR_DECR - -%% -program : /* empty */ - { - $$ = 0; - std_only = TRUE; - if (interactive) - { - printf ("s%s\n", BC_VERSION); - welcome(); - } - } - | program input_item - ; -input_item : semicolon_list ENDOFLINE - { run_code(); } - | function - { run_code(); } - | error ENDOFLINE - { - yyerrok; - init_gen() ; - } - ; -semicolon_list : /* empty */ - { $$ = 0; } - | statement_or_error - | semicolon_list ';' statement_or_error - | semicolon_list ';' - ; -statement_list : /* empty */ - { $$ = 0; } - | statement - | statement_list ENDOFLINE - | statement_list ENDOFLINE statement - | statement_list ';' - | statement_list ';' statement - ; -statement_or_error : statement - | error statement - { $$ = $2; } - ; -statement : Warranty - { warranty("s"); } - | expression - { - if ($1 & 1) - generate ("W"); - else - generate ("p"); - } - | STRING - { - $$ = 0; - generate ("w"); - generate ($1); - free ($1); - } - | Break - { - if (break_label == 0) - yyerror ("Break outside a for/while"); - else - { - sprintf (genstr, "J%1d:", break_label); - generate (genstr); - } - } - | Quit - { exit(0); } - | Return - { generate ("0R"); } - | Return '(' return_expression ')' - { generate ("R"); } - | For - { - $1 = break_label; - break_label = next_label++; - } - '(' expression ';' - { - $4 = next_label++; - sprintf (genstr, "pN%1d:", $4); - generate (genstr); - } - relational_expression ';' - { - $7 = next_label++; - sprintf (genstr, "B%1d:J%1d:", $7, break_label); - generate (genstr); - $$ = next_label++; - sprintf (genstr, "N%1d:", $$); - generate (genstr); - } - expression ')' - { - sprintf (genstr, "pJ%1d:N%1d:", $4, $7); - generate (genstr); - } - statement - { - sprintf (genstr, "J%1d:N%1d:", $9, - break_label); - generate (genstr); - break_label = $1; - } - | If '(' relational_expression ')' - { - $3 = next_label++; - sprintf (genstr, "Z%1d:", $3); - generate (genstr); - } - statement - { - sprintf (genstr, "N%1d:", $3); - generate (genstr); - } - | While - { - $1 = next_label++; - sprintf (genstr, "N%1d:", $1); - generate (genstr); - } - '(' relational_expression - { - $4 = break_label; - break_label = next_label++; - sprintf (genstr, "Z%1d:", break_label); - generate (genstr); - } - ')' statement - { - sprintf (genstr, "J%1d:N%1d:", $1, break_label); - generate (genstr); - break_label = $4; - } - | '{' statement_list '}' - { $$ = 0; } - ; -function : Define NAME '(' opt_parameter_list ')' '{' - ENDOFLINE opt_auto_define_list - { - check_params ($4,$8); - sprintf (genstr, "F%d,%s.%s[", lookup($2,FUNCT), - arg_str ($4), arg_str ($8)); - generate (genstr); - free_args ($4); - free_args ($8); - $1 = next_label; - next_label = 0; - } - statement_list ENDOFLINE '}' - { - generate ("0R]"); - next_label = $1; - } - ; -opt_parameter_list : /* empty */ - { $$ = NULL; } - | parameter_list - ; -parameter_list : NAME - { $$ = nextarg (NULL, lookup($1,SIMPLE), FALSE); } - | define_list ',' NAME - { $$ = nextarg ($1, lookup($3,SIMPLE), FALSE); } - ; -opt_auto_define_list : /* empty */ - { $$ = NULL; } - | Auto define_list ENDOFLINE - { $$ = $2; } - | Auto define_list ';' - { $$ = $2; } - ; -define_list : NAME - { $$ = nextarg (NULL, lookup($1,SIMPLE), FALSE); } - | NAME '[' ']' - { $$ = nextarg (NULL, lookup($1,ARRAY), FALSE); } - | define_list ',' NAME - { $$ = nextarg ($1, lookup($3,SIMPLE), FALSE); } - | define_list ',' NAME '[' ']' - { $$ = nextarg ($1, lookup($3,ARRAY), FALSE); } - ; -opt_argument_list : /* empty */ - { $$ = NULL; } - | argument_list - ; -argument_list : expression - { $$ = nextarg (NULL,0, FALSE); } - | argument_list ',' expression - { $$ = nextarg ($1,0, FALSE); } - ; -relational_expression : expression - { $$ = 0; } - | expression REL_OP expression - { - $$ = 0; - switch (*($2)) - { - case '=': - generate ("="); - break; - case '!': - generate ("#"); - break; - case '<': - if ($2[1] == '=') - generate ("{"); - else - generate ("<"); - break; - case '>': - if ($2[1] == '=') - generate ("}"); - else - generate (">"); - break; - } - } - ; -return_expression : /* empty */ - { - $$ = 0; - generate ("0"); - } - | expression - ; -expression : named_expression ASSIGN_OP - { - if ($2 != '=') - { - if ($1 < 0) - sprintf (genstr, "DL%d:", -$1); - else - sprintf (genstr, "l%d:", $1); - generate (genstr); - } - } - expression - { - $$ = 0; - if ($2 != '=') - { - sprintf (genstr, "%c", $2); - generate (genstr); - } - if ($1 < 0) - sprintf (genstr, "S%d:", -$1); - else - sprintf (genstr, "s%d:", $1); - generate (genstr); - } - | expression '+' expression - { generate ("+"); } - | expression '-' expression - { generate ("-"); } - | expression '*' expression - { generate ("*"); } - | expression '/' expression - { generate ("/"); } - | expression '%' expression - { generate ("%"); } - | expression '^' expression - { generate ("^"); } - | '-' expression %prec UNARY_MINUS - { generate ("n"); $$ = 1;} - | named_expression - { - $$ = 1; - if ($1 < 0) - sprintf (genstr, "L%d:", -$1); - else - sprintf (genstr, "l%d:", $1); - generate (genstr); - } - | NUMBER - { - int len = strlen($1); - $$ = 1; - if (len == 1 && *$1 == '0') - generate ("0"); - else - { - if (len == 1 && *$1 == '1') - generate ("1"); - else - { - generate ("K"); - generate ($1); - generate (":"); - } - free ($1); - } - } - | '(' expression ')' - { $$ = 1; } - | NAME '(' opt_argument_list ')' - { - $$ = 1; - if ($3 != NULL) - { - sprintf (genstr, "C%d,%s:", lookup($1,FUNCT), - arg_str ($3)); - free_args ($3); - } - else - sprintf (genstr, "C%d:", lookup($1,FUNCT)); - generate (genstr); - } - | INCR_DECR named_expression - { - $$ = 1; - if ($2 < 0) - { - if ($1 == '+') - sprintf (genstr, "DA%d:L%d:", -$2, -$2); - else - sprintf (genstr, "DM%d:L%d:", -$2, -$2); - } - else - { - if ($1 == '+') - sprintf (genstr, "i%d:l%d:", $2, $2); - else - sprintf (genstr, "d%d:l%d:", $2, $2); - } - generate (genstr); - } - | named_expression INCR_DECR - { - $$ = 1; - if ($1 < 0) - { - sprintf (genstr, "DL%d:x", -$1); - generate (genstr); - if ($2 == '+') - sprintf (genstr, "A%d:", -$1); - else - sprintf (genstr, "M%d:", -$1); - } - else - { - sprintf (genstr, "l%d:", $1); - generate (genstr); - if ($2 == '+') - sprintf (genstr, "i%d:", $1); - else - sprintf (genstr, "d%d:", $1); - } - generate (genstr); - } - | Length '(' expression ')' - { generate ("cL"); $$ = 1;} - | Sqrt '(' expression ')' - { generate ("cR"); $$ = 1;} - | Scale '(' expression ')' - { generate ("cS"); $$ = 1;} - ; -named_expression : NAME - { $$ = lookup($1,SIMPLE); } - | NAME '[' expression ']' - { $$ = lookup($1,ARRAY); } - | Ibase - { $$ = 0; } - | Obase - { $$ = 1; } - | Scale - { $$ = 2; } - ; - -%% diff --git a/src/bin/bc/bc/scan.c b/src/bin/bc/bc/scan.c deleted file mode 100644 index 317f1d685f..0000000000 --- a/src/bin/bc/bc/scan.c +++ /dev/null @@ -1,2259 +0,0 @@ -/* A lexical scanner generated by flex */ - -/* Scanner skeleton version: - * $Header: /tmp/bonefish/open-beos/current/src/apps/bin/bc/bc/scan.c,v 1.1 2004/05/26 08:01:51 korli Exp $ - */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 - -#include - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include -#include - -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_PROTOS -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include -#include -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#define YY_BUF_SIZE 16384 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern int yyleng; -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - - -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - }; - -static YY_BUFFER_STATE yy_current_buffer = 0; - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart YY_PROTO(( FILE *input_file )); - -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) - -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); - -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) - -typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -typedef int yy_state_type; -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 44 -#define YY_END_OF_BUFFER 45 -static yyconst short int yy_accept[298] = - { 0, - 0, 0, 2, 2, 45, 43, 38, 36, 30, 43, - 1, 31, 43, 27, 31, 27, 27, 26, 31, 42, - 34, 32, 34, 43, 27, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 43, 2, 2, 3, 2, 2, 1, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 38, - 34, 0, 41, 32, 28, 35, 42, 0, 39, 42, - 42, 0, 33, 37, 40, 40, 40, 40, 40, 40, - - 40, 40, 40, 40, 10, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 29, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 42, 0, 0, 42, 0, - 40, 40, 40, 40, 40, 9, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - - 2, 2, 2, 2, 2, 2, 16, 40, 40, 40, - 17, 19, 40, 40, 20, 40, 40, 40, 40, 6, - 18, 40, 40, 12, 40, 40, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 5, 40, 40, 40, - 14, 40, 40, 15, 24, 40, 13, 40, 11, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 40, 4, 40, 7, 25, 8, 40, 2, - 2, 2, 2, 2, 2, 2, 40, 21, 40, 2, - 2, 2, 23, 22, 2, 2, 0 - - } ; - -static yyconst int yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 5, 6, 1, 7, 8, 1, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 1, 18, 19, - 20, 21, 1, 1, 22, 22, 22, 22, 22, 22, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 23, 24, 25, 26, 27, 1, 28, 29, 30, 31, - - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 37, 49, 37, - 50, 37, 51, 52, 53, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst int yy_meta[54] = - { 0, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 1, 1, 1 - } ; - -static yyconst short int yy_base[302] = - { 0, - 0, 0, 53, 0, 525, 526, 522, 526, 503, 517, - 526, 501, 512, 526, 499, 95, 94, 94, 99, 105, - 498, 114, 497, 513, 495, 466, 468, 470, 479, 471, - 467, 0, 81, 102, 105, 479, 462, 458, 473, 94, - 104, 452, 0, 501, 526, 482, 139, 0, 481, 492, - 0, 479, 131, 132, 131, 125, 132, 478, 150, 477, - 493, 475, 160, 115, 117, 126, 130, 125, 446, 183, - 184, 186, 187, 123, 445, 180, 185, 192, 440, 489, - 526, 485, 526, 526, 526, 526, 158, 486, 526, 162, - 221, 485, 526, 526, 0, 440, 454, 444, 451, 437, - - 437, 442, 434, 451, 0, 432, 436, 436, 447, 438, - 437, 195, 444, 426, 425, 433, 526, 0, 466, 0, - 178, 0, 0, 0, 0, 222, 464, 0, 230, 233, - 463, 0, 417, 65, 189, 208, 193, 205, 213, 220, - 214, 235, 416, 218, 224, 227, 241, 234, 237, 243, - 246, 231, 232, 245, 0, 275, 460, 278, 279, 459, - 419, 432, 412, 422, 425, 0, 409, 408, 408, 406, - 418, 415, 404, 408, 401, 416, 398, 406, 397, 398, - 403, 287, 438, 288, 437, 182, 250, 239, 270, 275, - 391, 266, 268, 271, 273, 274, 288, 279, 285, 281, - - 299, 390, 292, 287, 293, 298, 0, 399, 400, 394, - 0, 0, 392, 401, 0, 385, 384, 398, 382, 0, - 0, 383, 395, 0, 398, 393, 376, 294, 303, 302, - 375, 374, 306, 312, 373, 305, 308, 313, 310, 372, - 371, 314, 317, 370, 335, 332, 0, 376, 384, 370, - 0, 379, 367, 0, 0, 371, 0, 370, 0, 362, - 325, 336, 322, 361, 137, 323, 360, 359, 331, 358, - 333, 357, 356, 0, 353, 0, 0, 0, 355, 349, - 343, 327, 342, 340, 334, 338, 346, 0, 238, 344, - 236, 339, 0, 0, 177, 102, 526, 392, 120, 395, - - 398 - } ; - -static yyconst short int yy_def[302] = - { 0, - 297, 1, 297, 3, 297, 297, 297, 297, 297, 298, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 299, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, - 299, 297, 300, 300, 297, 300, 301, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 300, 297, - 297, 298, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 299, 299, 299, 299, 299, 299, - - 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 297, 300, 300, 300, - 301, 300, 300, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 300, 297, 297, 297, 297, 297, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, - 299, 300, 300, 300, 300, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - - 63, 63, 63, 63, 63, 63, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 299, 299, 299, 299, 299, 299, 299, 63, - 63, 63, 63, 63, 63, 63, 299, 299, 299, 63, - 63, 63, 299, 299, 63, 63, 0, 297, 297, 297, - - 297 - } ; - -static yyconst short int yy_nxt[580] = - { 0, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, - 15, 16, 14, 17, 18, 19, 20, 14, 21, 22, - 23, 20, 14, 24, 14, 25, 6, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 32, 32, 35, 32, - 32, 36, 37, 38, 39, 40, 32, 32, 41, 32, - 14, 42, 14, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 51, 52, 53, 51, 54, 55, 56, 57, - 51, 58, 59, 60, 57, 51, 61, 51, 62, 43, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 69, - 69, 72, 69, 69, 73, 74, 75, 76, 77, 69, - - 69, 78, 69, 51, 79, 51, 86, 86, 102, 89, - 87, 186, 133, 84, 84, 87, 103, 88, 84, 90, - 93, 91, 95, 113, 93, 93, 91, 93, 92, 93, - 104, 115, 106, 81, 105, 128, 107, 114, 116, 93, - 108, 82, 125, 122, 123, 125, 129, 126, 130, 133, - 123, 123, 126, 130, 127, 131, 132, 137, 136, 135, - 132, 132, 133, 132, 133, 132, 139, 148, 138, 120, - 133, 283, 133, 133, 156, 132, 133, 133, 159, 156, - 82, 157, 122, 159, 133, 160, 133, 133, 133, 133, - 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, - - 133, 133, 133, 133, 133, 133, 133, 134, 133, 133, - 140, 150, 142, 144, 151, 147, 143, 145, 141, 153, - 187, 146, 176, 227, 133, 189, 154, 133, 152, 133, - 133, 133, 133, 133, 133, 90, 133, 91, 182, 133, - 133, 177, 91, 182, 92, 183, 184, 129, 188, 130, - 190, 184, 133, 185, 130, 133, 131, 191, 192, 193, - 133, 133, 194, 195, 196, 133, 197, 133, 198, 199, - 201, 133, 200, 203, 133, 204, 205, 228, 133, 133, - 206, 133, 133, 133, 133, 229, 133, 294, 133, 202, - 133, 156, 133, 133, 87, 159, 156, 133, 157, 87, - - 159, 88, 160, 182, 184, 230, 231, 236, 182, 184, - 183, 185, 232, 133, 233, 133, 234, 133, 133, 235, - 133, 133, 133, 237, 238, 239, 133, 240, 133, 241, - 243, 260, 133, 244, 133, 133, 246, 245, 261, 133, - 133, 133, 262, 264, 267, 133, 133, 263, 270, 133, - 133, 265, 133, 133, 266, 133, 268, 133, 269, 133, - 133, 133, 271, 272, 133, 280, 282, 281, 284, 133, - 133, 285, 133, 286, 133, 295, 291, 293, 133, 133, - 133, 133, 133, 133, 292, 133, 133, 133, 296, 133, - 133, 133, 82, 82, 82, 118, 290, 118, 121, 121, - - 121, 289, 288, 287, 133, 133, 133, 133, 133, 133, - 279, 278, 277, 276, 275, 274, 273, 133, 133, 133, - 133, 133, 133, 133, 259, 258, 257, 256, 255, 254, - 253, 252, 251, 250, 249, 248, 247, 242, 133, 159, - 156, 226, 225, 224, 223, 222, 221, 220, 219, 218, - 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, - 207, 159, 156, 133, 133, 91, 158, 119, 181, 180, - 179, 178, 175, 174, 173, 172, 171, 170, 169, 168, - 167, 166, 165, 164, 163, 162, 161, 91, 158, 83, - 80, 155, 149, 133, 123, 94, 120, 120, 123, 124, - - 123, 120, 119, 117, 112, 111, 110, 109, 101, 100, - 99, 98, 97, 96, 84, 94, 81, 81, 84, 85, - 84, 83, 81, 80, 297, 5, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297 - } ; - -static yyconst short int yy_chk[580] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - - 3, 3, 3, 3, 3, 3, 16, 17, 33, 19, - 18, 134, 134, 17, 16, 18, 33, 18, 19, 20, - 22, 20, 299, 40, 22, 22, 20, 22, 20, 22, - 34, 41, 35, 22, 34, 56, 35, 40, 41, 22, - 35, 47, 53, 47, 56, 54, 57, 55, 57, 296, - 53, 54, 55, 57, 55, 57, 59, 66, 65, 64, - 59, 59, 64, 59, 65, 59, 68, 74, 67, 59, - 74, 265, 68, 66, 87, 59, 63, 67, 90, 87, - 121, 87, 121, 90, 265, 90, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 70, 76, 71, 72, 77, 73, 71, 72, 70, 78, - 135, 72, 112, 186, 295, 137, 78, 76, 77, 186, - 70, 71, 77, 72, 73, 91, 135, 91, 126, 78, - 137, 112, 91, 126, 91, 126, 129, 130, 136, 130, - 138, 129, 138, 129, 130, 136, 130, 139, 140, 141, - 139, 141, 142, 144, 145, 144, 146, 140, 147, 148, - 150, 145, 149, 151, 146, 152, 153, 187, 152, 153, - 154, 148, 142, 291, 149, 188, 188, 289, 147, 150, - 150, 156, 154, 151, 158, 159, 156, 187, 156, 158, - - 159, 158, 159, 182, 184, 189, 190, 196, 182, 184, - 182, 184, 192, 192, 193, 193, 194, 189, 194, 195, - 195, 196, 190, 197, 198, 199, 198, 200, 200, 201, - 203, 228, 199, 204, 204, 197, 206, 205, 229, 203, - 205, 228, 230, 234, 238, 206, 201, 233, 243, 230, - 229, 236, 236, 233, 237, 237, 239, 239, 242, 234, - 238, 242, 245, 246, 243, 261, 263, 262, 266, 263, - 266, 269, 261, 271, 282, 290, 282, 287, 269, 246, - 271, 285, 245, 262, 286, 286, 292, 284, 292, 283, - 281, 290, 298, 298, 298, 300, 280, 300, 301, 301, - - 301, 279, 275, 273, 272, 270, 268, 267, 264, 260, - 258, 256, 253, 252, 250, 249, 248, 244, 241, 240, - 235, 232, 231, 227, 226, 225, 223, 222, 219, 218, - 217, 216, 214, 213, 210, 209, 208, 202, 191, 185, - 183, 181, 180, 179, 178, 177, 176, 175, 174, 173, - 172, 171, 170, 169, 168, 167, 165, 164, 163, 162, - 161, 160, 157, 143, 133, 131, 127, 119, 116, 115, - 114, 113, 111, 110, 109, 108, 107, 106, 104, 103, - 102, 101, 100, 99, 98, 97, 96, 92, 88, 82, - 80, 79, 75, 69, 62, 61, 60, 58, 52, 50, - - 49, 46, 44, 42, 39, 38, 37, 36, 31, 30, - 29, 28, 27, 26, 25, 24, 23, 21, 15, 13, - 12, 10, 9, 7, 5, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, - 297, 297, 297, 297, 297, 297, 297, 297, 297 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "scan.l" -#define INITIAL 0 -#line 2 "scan.l" -/* scan.l: the (f)lex description file for the scanner. */ - -/* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#include "bcdefs.h" -#include "bc.h" -#include "global.h" -#include "proto.h" -#include - -/* Using flex, we can ask for a smaller input buffer. With lex, this - does nothing! */ - -#ifdef SMALL_BUF -#undef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 512 -#endif - -/* Force . as last for now. */ -#define DOT_IS_LAST - -/* We want to define our own yywrap. */ -#undef yywrap -_PROTOTYPE(int yywrap, (void)); - -#if defined(LIBEDIT) -/* Support for the BSD libedit with history for - nicer input on the interactive part of input. */ - -#include - -/* Have input call the following function. */ -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - bcel_input((char *)buf, &result, max_size) - -/* Variables to help interface editline with bc. */ -static const char *bcel_line = (char *)NULL; -static int bcel_len = 0; - - -/* Required to get rid of that ugly ? default prompt! */ -char * -null_prompt (EditLine *el) -{ - return ""; -} - - -/* bcel_input puts upto MAX characters into BUF with the number put in - BUF placed in *RESULT. If the yy input file is the same as - stdin, use editline. Otherwise, just read it. -*/ - -static void -bcel_input (buf, result, max) - char *buf; - int *result; - int max; -{ - if (!edit || yyin != stdin) - { - while ( (*result = read( fileno(yyin), buf, max )) < 0 ) - if (errno != EINTR) - { - yyerror( "read() in flex scanner failed" ); - exit (1); - } - return; - } - - /* Do we need a new string? */ - if (bcel_len == 0) - { - bcel_line = el_gets(edit, &bcel_len); - if (bcel_line == NULL) { - /* end of file */ - *result = 0; - bcel_len = 0; - return; - } - if (bcel_len != 0) - history (hist, &histev, H_ENTER, bcel_line); - fflush (stdout); - } - - if (bcel_len <= max) - { - strncpy (buf, bcel_line, bcel_len); - *result = bcel_len; - bcel_len = 0; - } - else - { - strncpy (buf, bcel_line, max); - *result = max; - bcel_line += max; - bcel_len -= max; - } -} -#endif - -#ifdef READLINE -/* Support for the readline and history libraries. This allows - nicer input on the interactive part of input. */ - -/* Have input call the following function. */ -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - rl_input((char *)buf, &result, max_size) - -/* Variables to help interface readline with bc. */ -static char *rl_line = (char *)NULL; -static char *rl_start = (char *)NULL; -static int rl_len = 0; - -/* Definitions for readline access. */ -extern FILE *rl_instream; -_PROTOTYPE(char *readline, (char *)); - -/* rl_input puts upto MAX characters into BUF with the number put in - BUF placed in *RESULT. If the yy input file is the same as - rl_instream (stdin), use readline. Otherwise, just read it. -*/ - -static void -rl_input (buf, result, max) - char *buf; - int *result; - int max; -{ - if (yyin != rl_instream) - { - while ( (*result = read( fileno(yyin), buf, max )) < 0 ) - if (errno != EINTR) - { - yyerror( "read() in flex scanner failed" ); - exit (1); - } - return; - } - - /* Do we need a new string? */ - if (rl_len == 0) - { - if (rl_start) - free(rl_start); - rl_start = readline (""); - if (rl_start == NULL) { - /* end of file */ - *result = 0; - rl_len = 0; - return; - } - rl_line = rl_start; - rl_len = strlen (rl_line)+1; - if (rl_len != 1) - add_history (rl_line); - rl_line[rl_len-1] = '\n'; - fflush (stdout); - } - - if (rl_len <= max) - { - strncpy (buf, rl_line, rl_len); - *result = rl_len; - rl_len = 0; - } - else - { - strncpy (buf, rl_line, max); - *result = max; - rl_line += max; - rl_len -= max; - } -} -#endif - -#if !defined(READLINE) && !defined(LIBEDIT) - -/* MINIX returns from read with < 0 if SIGINT is encountered. - In flex, we can redefine YY_INPUT to the following. In lex, this - does nothing! */ -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ - if (errno != EINTR) \ - YY_FATAL_ERROR( "read() in flex scanner failed" ); -#endif - -#define slcomment 1 - -#line 809 "lex.yy.c" - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); -#else -extern int yywrap YY_PROTO(( void )); -#endif -#endif - -#ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput YY_PROTO(( void )); -#else -static int input YY_PROTO(( void )); -#endif -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif - -#else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 -#endif - -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ - -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) -#endif - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 222 "scan.l" - -#line 962 "lex.yy.c" - - if ( yy_init ) - { - yy_init = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 298 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 526 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - -do_action: /* This label is used only to access EOF actions. */ - - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 223 "scan.l" -{ - if (!std_only) - BEGIN(slcomment); - else - yyerror ("illegal character: #"); - } - YY_BREAK -case 2: -YY_RULE_SETUP -#line 229 "scan.l" -{ BEGIN(INITIAL); } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 230 "scan.l" -{ line_no++; BEGIN(INITIAL); return(ENDOFLINE); } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 231 "scan.l" -return(Define); - YY_BREAK -case 5: -YY_RULE_SETUP -#line 232 "scan.l" -return(Break); - YY_BREAK -case 6: -YY_RULE_SETUP -#line 233 "scan.l" -return(Quit); - YY_BREAK -case 7: -YY_RULE_SETUP -#line 234 "scan.l" -return(Length); - YY_BREAK -case 8: -YY_RULE_SETUP -#line 235 "scan.l" -return(Return); - YY_BREAK -case 9: -YY_RULE_SETUP -#line 236 "scan.l" -return(For); - YY_BREAK -case 10: -YY_RULE_SETUP -#line 237 "scan.l" -return(If); - YY_BREAK -case 11: -YY_RULE_SETUP -#line 238 "scan.l" -return(While); - YY_BREAK -case 12: -YY_RULE_SETUP -#line 239 "scan.l" -return(Sqrt); - YY_BREAK -case 13: -YY_RULE_SETUP -#line 240 "scan.l" -return(Scale); - YY_BREAK -case 14: -YY_RULE_SETUP -#line 241 "scan.l" -return(Ibase); - YY_BREAK -case 15: -YY_RULE_SETUP -#line 242 "scan.l" -return(Obase); - YY_BREAK -case 16: -YY_RULE_SETUP -#line 243 "scan.l" -return(Auto); - YY_BREAK -case 17: -YY_RULE_SETUP -#line 244 "scan.l" -return(Else); - YY_BREAK -case 18: -YY_RULE_SETUP -#line 245 "scan.l" -return(Read); - YY_BREAK -case 19: -YY_RULE_SETUP -#line 246 "scan.l" -return(Halt); - YY_BREAK -case 20: -YY_RULE_SETUP -#line 247 "scan.l" -return(Last); - YY_BREAK -case 21: -YY_RULE_SETUP -#line 248 "scan.l" -{ -#if defined(READLINE) || defined(LIBEDIT) - return(HistoryVar); -#else - yylval.s_value = strcopyof(yytext); return(NAME); -#endif - } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 256 "scan.l" -return(Warranty); - YY_BREAK -case 23: -YY_RULE_SETUP -#line 257 "scan.l" -return(Continue); - YY_BREAK -case 24: -YY_RULE_SETUP -#line 258 "scan.l" -return(Print); - YY_BREAK -case 25: -YY_RULE_SETUP -#line 259 "scan.l" -return(Limits); - YY_BREAK -case 26: -YY_RULE_SETUP -#line 260 "scan.l" -{ -#ifdef DOT_IS_LAST - return(Last); -#else - yyerror ("illegal character: %s",yytext); -#endif - } - YY_BREAK -case 27: -YY_RULE_SETUP -#line 267 "scan.l" -{ yylval.c_value = yytext[0]; - return((int)yytext[0]); } - YY_BREAK -case 28: -YY_RULE_SETUP -#line 269 "scan.l" -{ return(AND); } - YY_BREAK -case 29: -YY_RULE_SETUP -#line 270 "scan.l" -{ return(OR); } - YY_BREAK -case 30: -YY_RULE_SETUP -#line 271 "scan.l" -{ return(NOT); } - YY_BREAK -case 31: -YY_RULE_SETUP -#line 272 "scan.l" -{ yylval.c_value = yytext[0]; return((int)yytext[0]); } - YY_BREAK -case 32: -YY_RULE_SETUP -#line 273 "scan.l" -{ yylval.c_value = yytext[0]; return(ASSIGN_OP); } - YY_BREAK -case 33: -YY_RULE_SETUP -#line 274 "scan.l" -{ -#ifdef OLD_EQ_OP - char warn_save; - warn_save = warn_not_std; - warn_not_std = TRUE; - warn ("Old fashioned ="); - warn_not_std = warn_save; - yylval.c_value = yytext[1]; -#else - yylval.c_value = '='; - yyless (1); -#endif - return(ASSIGN_OP); - } - YY_BREAK -case 34: -YY_RULE_SETUP -#line 288 "scan.l" -{ yylval.s_value = strcopyof(yytext); return(REL_OP); } - YY_BREAK -case 35: -YY_RULE_SETUP -#line 289 "scan.l" -{ yylval.c_value = yytext[0]; return(INCR_DECR); } - YY_BREAK -case 36: -YY_RULE_SETUP -#line 290 "scan.l" -{ line_no++; return(ENDOFLINE); } - YY_BREAK -case 37: -YY_RULE_SETUP -#line 291 "scan.l" -{ line_no++; /* ignore a "quoted" newline */ } - YY_BREAK -case 38: -YY_RULE_SETUP -#line 292 "scan.l" -{ /* ignore spaces and tabs */ } - YY_BREAK -case 39: -YY_RULE_SETUP -#line 293 "scan.l" -{ - int c; - - for (;;) - { - while ( ((c=input()) != '*') && (c != EOF)) - /* eat it */ - if (c == '\n') line_no++; - if (c == '*') - { - while ( (c=input()) == '*') /* eat it*/; - if (c == '/') break; /* at end of comment */ - if (c == '\n') line_no++; - } - if (c == EOF) - { - fprintf (stderr,"EOF encountered in a comment.\n"); - break; - } - } - } - YY_BREAK -case 40: -YY_RULE_SETUP -#line 314 "scan.l" -{ yylval.s_value = strcopyof(yytext); return(NAME); } - YY_BREAK -case 41: -YY_RULE_SETUP -#line 315 "scan.l" -{ - unsigned char *look; - int count = 0; - yylval.s_value = strcopyof(yytext); - for (look = yytext; *look != 0; look++) - { - if (*look == '\n') line_no++; - if (*look == '"') count++; - } - if (count != 2) yyerror ("NUL character in string."); - return(STRING); - } - YY_BREAK -case 42: -YY_RULE_SETUP -#line 327 "scan.l" -{ - unsigned char *src, *dst; - int len; - /* remove a trailing decimal point. */ - len = strlen(yytext); - if (yytext[len-1] == '.') - yytext[len-1] = 0; - /* remove leading zeros. */ - src = yytext; - dst = yytext; - while (*src == '0') src++; - if (*src == 0) src--; - /* Copy strings removing the newlines. */ - while (*src != 0) - { - if (*src == '\\') - { - src++; src++; - line_no++; - } - else - *dst++ = *src++; - } - *dst = 0; - yylval.s_value = strcopyof(yytext); - return(NUMBER); - } - YY_BREAK -case 43: -YY_RULE_SETUP -#line 354 "scan.l" -{ - if (yytext[0] < ' ') - yyerror ("illegal character: ^%c",yytext[0] + '@'); - else - if (yytext[0] > '~') - yyerror ("illegal character: \\%03o", (int) yytext[0]); - else - yyerror ("illegal character: %s",yytext); - } - YY_BREAK -case 44: -YY_RULE_SETUP -#line 363 "scan.l" -ECHO; - YY_BREAK -#line 1361 "lex.yy.c" -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(slcomment): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ - - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; - - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; -#endif - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 298 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -#ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) -#else -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; -#endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 298 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 297); - - return yy_is_jam ? 0 : yy_current_state; - } - - -#ifndef YY_NO_UNPUT -#ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) -#else -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; -#endif - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ - - -#ifdef __cplusplus -static int yyinput() -#else -static int input() -#endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - - - return c; - } - - -#ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) -#else -void yyrestart( input_file ) -FILE *input_file; -#endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -#ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -#else -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; -#endif - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -#ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) -#else -void yy_load_buffer_state() -#endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) -#else -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; -#endif - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; - } - - -#ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) -#else -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; -#endif - { - if ( ! b ) - return; - - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); - - yy_flex_free( (void *) b ); - } - - -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -extern int isatty YY_PROTO(( int )); -#endif -#endif - -#ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) -#else -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; -#endif - - - { - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - -#if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } - - -#ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) -#else -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; -#endif - - { - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } - - -#ifndef YY_NO_SCAN_BUFFER -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) -#else -YY_BUFFER_STATE yy_scan_buffer( base, size ) -char *base; -yy_size_t size; -#endif - { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; - } -#endif - - -#ifndef YY_NO_SCAN_STRING -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) -#else -YY_BUFFER_STATE yy_scan_string( yy_str ) -yyconst char *yy_str; -#endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; - - return yy_scan_bytes( yy_str, len ); - } -#endif - - -#ifndef YY_NO_SCAN_BYTES -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) -#else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) -yyconst char *bytes; -int len; -#endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; - } -#endif - - -#ifndef YY_NO_PUSH_STATE -#ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) -#else -static void yy_push_state( new_state ) -int new_state; -#endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; - - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); - - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); - - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); - - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } - - yy_start_stack[yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); - } -#endif - - -#ifndef YY_NO_POP_STATE -static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif - - -#ifndef YY_NO_TOP_STATE -static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -#ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) -#else -static void yy_fatal_error( msg ) -char msg[]; -#endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - - - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) - - -/* Internal utility routines. */ - -#ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -#endif - -#ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; - } -#endif - - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { - return (void *) malloc( size ); - } - -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } - -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } - -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif -#line 363 "scan.l" - - - - -/* This is the way to get multiple files input into lex. */ - -int -yywrap() -{ - if (!open_new_file ()) return (1); /* EOF on standard in. */ - return (0); /* We have more input. */ -} diff --git a/src/bin/bc/bc/scan.l b/src/bin/bc/bc/scan.l deleted file mode 100644 index b4addaac59..0000000000 --- a/src/bin/bc/bc/scan.l +++ /dev/null @@ -1,374 +0,0 @@ -%{ -/* scan.l: the (f)lex description file for the scanner. */ - -/* This file is part of GNU bc. - Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#include "bcdefs.h" -#include "bc.h" -#include "global.h" -#include "proto.h" -#include - -/* Using flex, we can ask for a smaller input buffer. With lex, this - does nothing! */ - -#ifdef SMALL_BUF -#undef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 512 -#endif - -/* Force . as last for now. */ -#define DOT_IS_LAST - -/* We want to define our own yywrap. */ -#undef yywrap -_PROTOTYPE(int yywrap, (void)); - -#if defined(LIBEDIT) -/* Support for the BSD libedit with history for - nicer input on the interactive part of input. */ - -#include - -/* Have input call the following function. */ -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - bcel_input((char *)buf, &result, max_size) - -/* Variables to help interface editline with bc. */ -static const char *bcel_line = (char *)NULL; -static int bcel_len = 0; - - -/* Required to get rid of that ugly ? default prompt! */ -char * -null_prompt (EditLine *el) -{ - return ""; -} - - -/* bcel_input puts upto MAX characters into BUF with the number put in - BUF placed in *RESULT. If the yy input file is the same as - stdin, use editline. Otherwise, just read it. -*/ - -static void -bcel_input (buf, result, max) - char *buf; - int *result; - int max; -{ - if (!edit || yyin != stdin) - { - while ( (*result = read( fileno(yyin), buf, max )) < 0 ) - if (errno != EINTR) - { - yyerror( "read() in flex scanner failed" ); - exit (1); - } - return; - } - - /* Do we need a new string? */ - if (bcel_len == 0) - { - bcel_line = el_gets(edit, &bcel_len); - if (bcel_line == NULL) { - /* end of file */ - *result = 0; - bcel_len = 0; - return; - } - if (bcel_len != 0) - history (hist, &histev, H_ENTER, bcel_line); - fflush (stdout); - } - - if (bcel_len <= max) - { - strncpy (buf, bcel_line, bcel_len); - *result = bcel_len; - bcel_len = 0; - } - else - { - strncpy (buf, bcel_line, max); - *result = max; - bcel_line += max; - bcel_len -= max; - } -} -#endif - -#ifdef READLINE -/* Support for the readline and history libraries. This allows - nicer input on the interactive part of input. */ - -/* Have input call the following function. */ -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - rl_input((char *)buf, &result, max_size) - -/* Variables to help interface readline with bc. */ -static char *rl_line = (char *)NULL; -static char *rl_start = (char *)NULL; -static int rl_len = 0; - -/* Definitions for readline access. */ -extern FILE *rl_instream; -_PROTOTYPE(char *readline, (char *)); - -/* rl_input puts upto MAX characters into BUF with the number put in - BUF placed in *RESULT. If the yy input file is the same as - rl_instream (stdin), use readline. Otherwise, just read it. -*/ - -static void -rl_input (buf, result, max) - char *buf; - int *result; - int max; -{ - if (yyin != rl_instream) - { - while ( (*result = read( fileno(yyin), buf, max )) < 0 ) - if (errno != EINTR) - { - yyerror( "read() in flex scanner failed" ); - exit (1); - } - return; - } - - /* Do we need a new string? */ - if (rl_len == 0) - { - if (rl_start) - free(rl_start); - rl_start = readline (""); - if (rl_start == NULL) { - /* end of file */ - *result = 0; - rl_len = 0; - return; - } - rl_line = rl_start; - rl_len = strlen (rl_line)+1; - if (rl_len != 1) - add_history (rl_line); - rl_line[rl_len-1] = '\n'; - fflush (stdout); - } - - if (rl_len <= max) - { - strncpy (buf, rl_line, rl_len); - *result = rl_len; - rl_len = 0; - } - else - { - strncpy (buf, rl_line, max); - *result = max; - rl_line += max; - rl_len -= max; - } -} -#endif - -#if !defined(READLINE) && !defined(LIBEDIT) - -/* MINIX returns from read with < 0 if SIGINT is encountered. - In flex, we can redefine YY_INPUT to the following. In lex, this - does nothing! */ -#undef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - while ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ - if (errno != EINTR) \ - YY_FATAL_ERROR( "read() in flex scanner failed" ); -#endif - -%} -DIGIT [0-9A-F] -LETTER [a-z] -%s slcomment -%% -"#" { - if (!std_only) - BEGIN(slcomment); - else - yyerror ("illegal character: #"); - } -[^\n]* { BEGIN(INITIAL); } -"\n" { line_no++; BEGIN(INITIAL); return(ENDOFLINE); } -define return(Define); -break return(Break); -quit return(Quit); -length return(Length); -return return(Return); -for return(For); -if return(If); -while return(While); -sqrt return(Sqrt); -scale return(Scale); -ibase return(Ibase); -obase return(Obase); -auto return(Auto); -else return(Else); -read return(Read); -halt return(Halt); -last return(Last); -history { -#if defined(READLINE) || defined(LIBEDIT) - return(HistoryVar); -#else - yylval.s_value = strcopyof(yytext); return(NAME); -#endif - } - -warranty return(Warranty); -continue return(Continue); -print return(Print); -limits return(Limits); -"." { -#ifdef DOT_IS_LAST - return(Last); -#else - yyerror ("illegal character: %s",yytext); -#endif - } -"+"|"-"|";"|"("|")"|"{"|"}"|"["|"]"|","|"^" { yylval.c_value = yytext[0]; - return((int)yytext[0]); } -&& { return(AND); } -\|\| { return(OR); } -"!" { return(NOT); } -"*"|"/"|"%" { yylval.c_value = yytext[0]; return((int)yytext[0]); } -"="|\+=|-=|\*=|\/=|%=|\^= { yylval.c_value = yytext[0]; return(ASSIGN_OP); } -=\+|=-|=\*|=\/|=%|=\^ { -#ifdef OLD_EQ_OP - char warn_save; - warn_save = warn_not_std; - warn_not_std = TRUE; - warn ("Old fashioned ="); - warn_not_std = warn_save; - yylval.c_value = yytext[1]; -#else - yylval.c_value = '='; - yyless (1); -#endif - return(ASSIGN_OP); - } -==|\<=|\>=|\!=|"<"|">" { yylval.s_value = strcopyof(yytext); return(REL_OP); } -\+\+|-- { yylval.c_value = yytext[0]; return(INCR_DECR); } -"\n" { line_no++; return(ENDOFLINE); } -\\\n { line_no++; /* ignore a "quoted" newline */ } -[ \t]+ { /* ignore spaces and tabs */ } -"/*" { - int c; - - for (;;) - { - while ( ((c=input()) != '*') && (c != EOF)) - /* eat it */ - if (c == '\n') line_no++; - if (c == '*') - { - while ( (c=input()) == '*') /* eat it*/; - if (c == '/') break; /* at end of comment */ - if (c == '\n') line_no++; - } - if (c == EOF) - { - fprintf (stderr,"EOF encountered in a comment.\n"); - break; - } - } - } -[a-z][a-z0-9_]* { yylval.s_value = strcopyof(yytext); return(NAME); } -\"[^\"]*\" { - 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: \\%03o", (int) yytext[0]); - else - yyerror ("illegal character: %s",yytext); - } -%% - - - -/* This is the way to get multiple files input into lex. */ - -int -yywrap() -{ - if (!open_new_file ()) return (1); /* EOF on standard in. */ - return (0); /* We have more input. */ -} diff --git a/src/bin/bc/bc/storage.c b/src/bin/bc/bc/storage.c deleted file mode 100644 index 10ebf5cdc6..0000000000 --- a/src/bin/bc/bc/storage.c +++ /dev/null @@ -1,1067 +0,0 @@ -/* storage.c: Code and data storage manipulations. This includes labels. */ - -/* This file is part of GNU bc. - Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#include "bcdefs.h" -#include "global.h" -#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; -#if defined(READLINE) || defined(LIBEDIT) - n_history = -1; -#endif - c_code = FALSE; - bc_init_numbers(); -} - -/* Three functions for increasing the number of functions, variables, or - arrays that are needed. This adds another 32 of the requested object. */ - -void -more_functions (VOID) -{ - int old_count; - int indx; - bc_function *old_f; - bc_function *f; - char **old_names; - - /* Save old information. */ - old_count = f_count; - old_f = functions; - old_names = f_names; - - /* Add a fixed amount and allocate new space. */ - f_count += STORE_INCR; - functions = (bc_function *) bc_malloc (f_count*sizeof (bc_function)); - f_names = (char **) bc_malloc (f_count*sizeof (char *)); - - /* Copy old ones. */ - for (indx = 0; indx < old_count; indx++) - { - functions[indx] = old_f[indx]; - f_names[indx] = old_names[indx]; - } - - /* Initialize the new ones. */ - for (; indx < f_count; indx++) - { - f = &functions[indx]; - f->f_defined = FALSE; - f->f_body = (char *) bc_malloc (BC_START_SIZE); - f->f_body_size = BC_START_SIZE; - f->f_code_size = 0; - f->f_label = NULL; - f->f_autos = NULL; - f->f_params = NULL; - } - - /* Free the old elements. */ - if (old_count != 0) - { - free (old_f); - free (old_names); - } -} - -void -more_variables () -{ - int indx; - int old_count; - bc_var **old_var; - char **old_names; - - /* Save the old values. */ - old_count = v_count; - old_var = variables; - old_names = v_names; - - /* Increment by a fixed amount and allocate. */ - v_count += STORE_INCR; - variables = (bc_var **) bc_malloc (v_count*sizeof(bc_var *)); - v_names = (char **) bc_malloc (v_count*sizeof(char *)); - - /* Copy the old variables. */ - for (indx = 3; indx < old_count; indx++) - variables[indx] = old_var[indx]; - - /* 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) - int func; -{ - bc_function *f; - bc_label_group *lg; - - /* Set the pointer to the function. */ - f = &functions[func]; - f->f_defined = FALSE; - /* XXX restore f_body to initial size??? */ - f->f_code_size = 0; - if (f->f_autos != NULL) - { - free_args (f->f_autos); - f->f_autos = NULL; - } - if (f->f_params != NULL) - { - free_args (f->f_params); - f->f_params = NULL; - } - while (f->f_label != NULL) - { - lg = f->f_label->l_next; - free (f->f_label); - f->f_label = lg; - } -} - - -/* Pop the function execution stack and return the top. */ - -int -fpop() -{ - fstack_rec *temp; - int retval; - - if (fn_stack != NULL) - { - temp = fn_stack; - fn_stack = temp->s_next; - retval = temp->s_val; - free (temp); - } - else - { - retval = 0; - rt_error ("function stack underflow, contact maintainer."); - } - return (retval); -} - - -/* Push VAL on to the function stack. */ - -void -fpush (val) - int val; -{ - fstack_rec *temp; - - temp = (fstack_rec *) bc_malloc (sizeof (fstack_rec)); - temp->s_next = fn_stack; - temp->s_val = val; - fn_stack = temp; -} - - -/* Pop and discard the top element of the regular execution stack. */ - -void -pop () -{ - estack_rec *temp; - - if (ex_stack != NULL) - { - temp = ex_stack; - ex_stack = temp->s_next; - bc_free_num (&temp->s_num); - free (temp); - } -} - - -/* Push a copy of NUM on to the regular execution stack. */ - -void -push_copy (num) - bc_num num; -{ - estack_rec *temp; - - temp = (estack_rec *) bc_malloc (sizeof (estack_rec)); - temp->s_num = bc_copy_num (num); - temp->s_next = ex_stack; - ex_stack = temp; -} - - -/* Push NUM on to the regular execution stack. Do NOT push a copy. */ - -void -push_num (num) - bc_num num; -{ - estack_rec *temp; - - temp = (estack_rec *) bc_malloc (sizeof (estack_rec)); - temp->s_num = num; - temp->s_next = ex_stack; - ex_stack = temp; -} - - -/* Make sure the ex_stack has at least DEPTH elements on it. - Return TRUE if it has at least DEPTH elements, otherwise - return FALSE. */ - -char -check_stack (depth) - int depth; -{ - estack_rec *temp; - - temp = ex_stack; - while ((temp != NULL) && (depth > 0)) - { - temp = temp->s_next; - depth--; - } - if (depth > 0) - { - rt_error ("Stack error."); - return FALSE; - } - return TRUE; -} - - -/* The following routines manipulate simple variables and - array variables. */ - -/* get_var returns a pointer to the variable VAR_NAME. If one does not - exist, one is created. */ - -bc_var * -get_var (var_name) - int var_name; -{ - bc_var *var_ptr; - - var_ptr = variables[var_name]; - if (var_ptr == NULL) - { - var_ptr = variables[var_name] = (bc_var *) bc_malloc (sizeof (bc_var)); - bc_init_num (&var_ptr->v_value); - } - return var_ptr; -} - - -/* get_array_num returns the address of the bc_num in the array - structure. If more structure is requried to get to the index, - this routine does the work to create that structure. VAR_INDEX - is a zero based index into the arrays storage array. INDEX is - the index into the bc array. */ - -bc_num * -get_array_num (var_index, 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] = bc_copy_num(_zero_); - } - a_var->a_tree = temp; - a_var->a_depth++; - } - - /* Find the indexed variable. */ - temp = a_var->a_tree; - while ( log-- > 1) - { - ix1 = sub[log]; - if (temp->n_items.n_down[ix1] == NULL) - { - temp->n_items.n_down[ix1] = - (bc_array_node *) bc_malloc (sizeof(bc_array_node)); - temp = temp->n_items.n_down[ix1]; - if (log > 1) - for (ix=0; ix < NODE_SIZE; ix++) - temp->n_items.n_down[ix] = NULL; - else - for (ix=0; ix < NODE_SIZE; ix++) - temp->n_items.n_num[ix] = bc_copy_num(_zero_); - } - else - temp = temp->n_items.n_down[ix1]; - } - - /* Return the address of the indexed variable. */ - return &(temp->n_items.n_num[sub[0]]); -} - - -/* Store the top of the execution stack into VAR_NAME. - This includes the special variables ibase, obase, and scale. */ - -void -store_var (var_name) - int var_name; -{ - bc_var *var_ptr; - long temp; - char toobig; - - if (var_name > 3) - { - /* It is a simple variable. */ - var_ptr = get_var (var_name); - if (var_ptr != NULL) - { - bc_free_num(&var_ptr->v_value); - var_ptr->v_value = bc_copy_num (ex_stack->s_num); - } - } - else - { - /* It is a special variable... */ - toobig = FALSE; - temp = 0; - if (bc_is_neg (ex_stack->s_num)) - { - switch (var_name) - { - case 0: - rt_warn ("negative ibase, set to 2"); - temp = 2; - break; - case 1: - rt_warn ("negative obase, set to 2"); - temp = 2; - break; - case 2: - rt_warn ("negative scale, set to 0"); - temp = 0; - break; -#if defined(READLINE) || defined(LIBEDIT) - case 3: - temp = -1; - break; -#endif - } - } - else - { - temp = bc_num2long (ex_stack->s_num); - if (!bc_is_zero (ex_stack->s_num) && temp == 0) - toobig = TRUE; - } - switch (var_name) - { - case 0: - if (temp < 2 && !toobig) - { - i_base = 2; - rt_warn ("ibase too small, set to 2"); - } - else - if (temp > 16 || toobig) - { - i_base = 16; - rt_warn ("ibase too large, set to 16"); - } - else - i_base = (int) temp; - break; - - case 1: - if (temp < 2 && !toobig) - { - o_base = 2; - rt_warn ("obase too small, set to 2"); - } - else - if (temp > BC_BASE_MAX || toobig) - { - o_base = BC_BASE_MAX; - rt_warn ("obase too large, set to %d", BC_BASE_MAX); - } - else - o_base = (int) temp; - break; - - case 2: - /* WARNING: The following if statement may generate a compiler - warning if INT_MAX == LONG_MAX. This is NOT a problem. */ - if (temp > BC_SCALE_MAX || toobig ) - { - scale = BC_SCALE_MAX; - rt_warn ("scale too large, set to %d", BC_SCALE_MAX); - } - else - scale = (int) temp; - break; - -#if defined(READLINE) || defined(LIBEDIT) - case 3: - if (toobig) - { - temp = -1; - rt_warn ("history too large, set to unlimited"); - UNLIMIT_HISTORY; - } - else - { - n_history = temp; - if (temp < 0) - UNLIMIT_HISTORY; - else - HISTORY_SIZE(n_history); - } -#endif - } - } -} - - -/* Store the top of the execution stack into array VAR_NAME. - VAR_NAME is the name of an array, and the next to the top - of stack for the index into the array. */ - -void -store_array (var_name) - int var_name; -{ - bc_num *num_ptr; - long index; - - if (!check_stack(2)) return; - index = bc_num2long (ex_stack->s_next->s_num); - if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !bc_is_zero(ex_stack->s_next->s_num))) - rt_error ("Array %s subscript out of bounds.", a_names[var_name]); - else - { - num_ptr = get_array_num (var_name, index); - if (num_ptr != NULL) - { - bc_free_num (num_ptr); - *num_ptr = bc_copy_num (ex_stack->s_num); - bc_free_num (&ex_stack->s_next->s_num); - ex_stack->s_next->s_num = ex_stack->s_num; - bc_init_num (&ex_stack->s_num); - pop(); - } - } -} - - -/* Load a copy of VAR_NAME on to the execution stack. This includes - the special variables ibase, obase and scale. */ - -void -load_var (var_name) - int var_name; -{ - bc_var *var_ptr; - - switch (var_name) - { - - case 0: - /* Special variable ibase. */ - push_copy (_zero_); - bc_int2num (&ex_stack->s_num, i_base); - break; - - case 1: - /* Special variable obase. */ - push_copy (_zero_); - bc_int2num (&ex_stack->s_num, o_base); - break; - - case 2: - /* Special variable scale. */ - push_copy (_zero_); - bc_int2num (&ex_stack->s_num, scale); - break; - -#if defined(READLINE) || defined(LIBEDIT) - case 3: - /* Special variable history. */ - push_copy (_zero_); - bc_int2num (&ex_stack->s_num, n_history); - break; -#endif - - default: - /* It is a simple variable. */ - var_ptr = variables[var_name]; - if (var_ptr != NULL) - push_copy (var_ptr->v_value); - else - push_copy (_zero_); - } -} - - -/* Load a copy of VAR_NAME on to the execution stack. This includes - the special variables ibase, obase and scale. */ - -void -load_array (var_name) - int var_name; -{ - bc_num *num_ptr; - long index; - - if (!check_stack(1)) return; - index = bc_num2long (ex_stack->s_num); - if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !bc_is_zero(ex_stack->s_num))) - rt_error ("Array %s subscript out of bounds.", a_names[var_name]); - else - { - num_ptr = get_array_num (var_name, 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; - -#if defined(READLINE) || defined(LIBEDIT) - case 3: /* history */ - n_history--; - if (n_history >= 0) - HISTORY_SIZE(n_history); - else - { - n_history = -1; - rt_warn ("history is negative, set to unlimited"); - UNLIMIT_HISTORY; - } -#endif - - default: /* It is a simple variable. */ - var_ptr = get_var (var_name); - if (var_ptr != NULL) - bc_sub (var_ptr->v_value,_one_,&var_ptr->v_value, 0); - } -} - - -/* Decrement VAR_NAME by one. VAR_NAME is an array, and the top of - the execution stack is the index and it is popped off the stack. */ - -void -decr_array (var_name) - int var_name; -{ - bc_num *num_ptr; - long index; - - /* It is an array variable. */ - if (!check_stack (1)) return; - index = bc_num2long (ex_stack->s_num); - if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !bc_is_zero (ex_stack->s_num))) - rt_error ("Array %s subscript out of bounds.", a_names[var_name]); - else - { - num_ptr = get_array_num (var_name, index); - if (num_ptr != NULL) - { - pop (); - bc_sub (*num_ptr, _one_, num_ptr, 0); - } - } -} - - -/* Increment VAR_NAME by one. This includes the special variables - ibase, obase, and scale. */ - -void -incr_var (var_name) - int var_name; -{ - bc_var *var_ptr; - - switch (var_name) - { - - case 0: /* ibase */ - if (i_base < 16) - i_base++; - else - rt_warn ("ibase too big in ++"); - break; - - case 1: /* obase */ - if (o_base < BC_BASE_MAX) - o_base++; - else - rt_warn ("obase too big in ++"); - break; - - case 2: - if (scale < BC_SCALE_MAX) - scale++; - else - rt_warn ("Scale too big in ++"); - break; - -#if defined(READLINE) || defined(LIBEDIT) - case 3: /* history */ - n_history++; - if (n_history > 0) - HISTORY_SIZE(n_history); - else - { - n_history = -1; - rt_warn ("history set to unlimited"); - UNLIMIT_HISTORY; - } -#endif - - default: /* It is a simple variable. */ - var_ptr = get_var (var_name); - if (var_ptr != NULL) - bc_add (var_ptr->v_value, _one_, &var_ptr->v_value, 0); - - } -} - - -/* Increment VAR_NAME by one. VAR_NAME is an array and top of - execution stack is the index and is popped off the stack. */ - -void -incr_array (var_name) - int var_name; -{ - bc_num *num_ptr; - long index; - - if (!check_stack (1)) return; - index = bc_num2long (ex_stack->s_num); - if (index < 0 || index > BC_DIM_MAX || - (index == 0 && !bc_is_zero (ex_stack->s_num))) - rt_error ("Array %s subscript out of bounds.", a_names[var_name]); - else - { - num_ptr = get_array_num (var_name, index); - if (num_ptr != NULL) - { - pop (); - bc_add (*num_ptr, _one_, num_ptr, 0); - } - } -} - - -/* Routines for processing autos variables and parameters. */ - -/* NAME is an auto variable that needs to be pushed on its stack. */ - -void -auto_var (name) - int name; -{ - bc_var *v_temp; - bc_var_array *a_temp; - int ix; - - if (name > 0) - { - /* A simple variable. */ - ix = name; - v_temp = (bc_var *) bc_malloc (sizeof (bc_var)); - v_temp->v_next = variables[ix]; - bc_init_num (&v_temp->v_value); - variables[ix] = v_temp; - } - else - { - /* An array variable. */ - ix = -name; - a_temp = (bc_var_array *) bc_malloc (sizeof (bc_var_array)); - a_temp->a_next = arrays[ix]; - a_temp->a_value = NULL; - a_temp->a_param = FALSE; - arrays[ix] = a_temp; - } -} - - -/* Free_a_tree frees everything associated with an array variable tree. - This is used when popping an array variable off its auto stack. */ - -void -free_a_tree ( root, depth ) - bc_array_node *root; - int depth; -{ - int ix; - - if (root != NULL) - { - if (depth > 1) - for (ix = 0; ix < NODE_SIZE; ix++) - free_a_tree (root->n_items.n_down[ix], depth-1); - else - for (ix = 0; ix < NODE_SIZE; ix++) - bc_free_num ( &(root->n_items.n_num[ix])); - free (root); - } -} - - -/* LIST is an NULL terminated list of varible names that need to be - popped off their auto stacks. */ - -void -pop_vars (list) - arg_list *list; -{ - bc_var *v_temp; - bc_var_array *a_temp; - int ix; - - while (list != NULL) - { - ix = list->av_name; - if (ix > 0) - { - /* A simple variable. */ - v_temp = variables[ix]; - if (v_temp != NULL) - { - variables[ix] = v_temp->v_next; - bc_free_num (&v_temp->v_value); - free (v_temp); - } - } - else - { - /* An array variable. */ - ix = -ix; - a_temp = arrays[ix]; - if (a_temp != NULL) - { - arrays[ix] = a_temp->a_next; - if (!a_temp->a_param && a_temp->a_value != NULL) - { - free_a_tree (a_temp->a_value->a_tree, - a_temp->a_value->a_depth); - free (a_temp->a_value); - } - free (a_temp); - } - } - list = list->next; - } -} - -/* COPY_NODE: Copies an array node for a call by value parameter. */ -bc_array_node * -copy_tree (ary_node, depth) - bc_array_node *ary_node; - int depth; -{ - bc_array_node *res = (bc_array_node *) bc_malloc (sizeof(bc_array_node)); - int i; - - if (depth > 1) - for (i=0; in_items.n_down[i] != NULL) - res->n_items.n_down[i] = - copy_tree (ary_node->n_items.n_down[i], depth - 1); - else - res->n_items.n_down[i] = NULL; - else - for (i=0; in_items.n_num[i] != NULL) - res->n_items.n_num[i] = bc_copy_num (ary_node->n_items.n_num[i]); - else - res->n_items.n_num[i] = NULL; - return res; -} - -/* COPY_ARRAY: Copies an array for a call by value array parameter. - ARY is the pointer to the bc_array structure. */ - -bc_array * -copy_array (ary) - bc_array *ary; -{ - bc_array *res = (bc_array *) bc_malloc (sizeof(bc_array)); - res->a_depth = ary->a_depth; - res->a_tree = copy_tree (ary->a_tree, ary->a_depth); - return (res); -} - - -/* A call is being made to FUNC. The call types are at PC. Process - the parameters by doing an auto on the parameter variable and then - store the value at the new variable or put a pointer the the array - variable. */ - -void -process_params (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; - bc_init_num (&ex_stack->s_num); - variables[ix] = v_temp; - } - else - if ((ch == '1') && (params->av_name < 0)) - { - /* The variables is an array variable. */ - - /* Compute source index and make sure some structure exists. */ - ix = (int) bc_num2long (ex_stack->s_num); - n_temp = get_array_num (ix, 0); - - /* Push a new array and Compute Destination index */ - auto_var (params->av_name); - ix1 = -params->av_name; - - /* Set up the correct pointers in the structure. */ - if (ix == ix1) - a_src = arrays[ix]->a_next; - else - a_src = arrays[ix]; - a_dest = arrays[ix1]; - if (params->arg_is_var) - { - a_dest->a_param = TRUE; - a_dest->a_value = a_src->a_value; - } - else - { - a_dest->a_param = FALSE; - a_dest->a_value = copy_array (a_src->a_value); - } - } - else - { - if (params->av_name < 0) - rt_error ("Parameter type mismatch parameter %s.", - a_names[-params->av_name]); - else - rt_error ("Parameter type mismatch, parameter %s.", - v_names[params->av_name]); - params++; - } - pop (); - } - else - { - rt_error ("Parameter number mismatch"); - return; - } - params = params->next; - } - if (params != NULL) - rt_error ("Parameter number mismatch"); -} diff --git a/src/bin/bc/bc/util.c b/src/bin/bc/bc/util.c deleted file mode 100644 index c305c2e375..0000000000 --- a/src/bin/bc/bc/util.c +++ /dev/null @@ -1,873 +0,0 @@ -/* util.c: Utility routines for bc. */ - -/* This file is part of GNU bc. - Copyright (C) 1991-1994, 1997, 2000 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111 USA - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - - -#include "bcdefs.h" -#ifndef VARARGS -#include -#else -#include -#endif -#include "global.h" -#include "proto.h" - - -/* strcopyof mallocs new memory and copies a string to to the new - memory. */ - -char * -strcopyof (str) - char *str; -{ - char *temp; - - temp = (char *) bc_malloc (strlen (str)+1); - return (strcpy (temp,str)); -} - - -/* nextarg adds another value to the list of arguments. */ - -arg_list * -nextarg (args, val, is_var) - arg_list *args; - int val; - int is_var; -{ arg_list *temp; - - temp = (arg_list *) bc_malloc (sizeof (arg_list)); - temp->av_name = val; - temp->arg_is_var = is_var; - temp->next = args; - - return (temp); -} - - -/* For generate, we must produce a string in the form - "val,val,...,val". We also need a couple of static variables - for retaining old generated strings. It also uses a recursive - function that builds the string. */ - -static char *arglist1 = NULL, *arglist2 = NULL; - - -/* make_arg_str does the actual construction of the argument string. - ARGS is the pointer to the list and LEN is the maximum number of - characters needed. 1 char is the minimum needed. - */ - -_PROTOTYPE (static char *make_arg_str, (arg_list *args, int len)); - -static char * -make_arg_str (args, len) - arg_list *args; - int len; -{ - char *temp; - char sval[20]; - - /* Recursive call. */ - if (args != NULL) - temp = make_arg_str (args->next, len+12); - else - { - temp = (char *) bc_malloc (len); - *temp = 0; - return temp; - } - - /* Add the current number to the end of the string. */ - if (args->arg_is_var) - if (len != 1) - sprintf (sval, "*%d,", args->av_name); - else - sprintf (sval, "*%d", args->av_name); - else - if (len != 1) - sprintf (sval, "%d,", args->av_name); - else - sprintf (sval, "%d", args->av_name); - temp = strcat (temp, sval); - return (temp); -} - -char * -arg_str (args) - arg_list *args; -{ - if (arglist2 != NULL) - free (arglist2); - arglist2 = arglist1; - arglist1 = make_arg_str (args, 1); - return (arglist1); -} - -char * -call_str (args) - arg_list *args; -{ - arg_list *temp; - int arg_count; - int ix; - - if (arglist2 != NULL) - free (arglist2); - arglist2 = arglist1; - - /* Count the number of args and add the 0's and 1's. */ - for (temp = args, arg_count = 0; temp != NULL; temp = temp->next) - arg_count++; - arglist1 = (char *) bc_malloc(arg_count+1); - for (temp = args, ix=0; temp != NULL; temp = temp->next) - arglist1[ix++] = ( temp->av_name ? '1' : '0'); - arglist1[ix] = 0; - - return (arglist1); -} - -/* free_args frees an argument list ARGS. */ - -void -free_args (args) - arg_list *args; -{ - arg_list *temp; - - temp = args; - while (temp != NULL) - { - args = args->next; - free (temp); - temp = args; - } -} - - -/* Check for valid parameter (PARAMS) and auto (AUTOS) lists. - There must be no duplicates any where. Also, this is where - warnings are generated for array parameters. */ - -void -check_params ( params, autos ) - arg_list *params, *autos; -{ - arg_list *tmp1, *tmp2; - - /* Check for duplicate parameters. */ - if (params != NULL) - { - tmp1 = params; - while (tmp1 != NULL) - { - tmp2 = tmp1->next; - while (tmp2 != NULL) - { - if (tmp2->av_name == tmp1->av_name) - yyerror ("duplicate parameter names"); - tmp2 = tmp2->next; - } - if (tmp1->arg_is_var) - warn ("Variable array parameter"); - tmp1 = tmp1->next; - } - } - - /* Check for duplicate autos. */ - if (autos != NULL) - { - tmp1 = autos; - while (tmp1 != NULL) - { - tmp2 = tmp1->next; - while (tmp2 != NULL) - { - if (tmp2->av_name == tmp1->av_name) - yyerror ("duplicate auto variable names"); - tmp2 = tmp2->next; - } - if (tmp1->arg_is_var) - yyerror ("* not allowed here"); - tmp1 = tmp1->next; - } - } - - /* Check for duplicate between parameters and autos. */ - if ((params != NULL) && (autos != NULL)) - { - tmp1 = params; - while (tmp1 != NULL) - { - tmp2 = autos; - while (tmp2 != NULL) - { - if (tmp2->av_name == tmp1->av_name) - yyerror ("variable in both parameter and auto lists"); - tmp2 = tmp2->next; - } - tmp1 = tmp1->next; - } - } -} - - -/* Initialize the code generator the parser. */ - -void -init_gen () -{ - /* Get things ready. */ - break_label = 0; - continue_label = 0; - next_label = 1; - out_count = 2; - if (compile_only) - printf ("@i"); - else - init_load (); - had_error = FALSE; - did_gen = FALSE; -} - - -/* generate code STR for the machine. */ - -void -generate (str) - char *str; -{ - did_gen = TRUE; - if (compile_only) - { - printf ("%s",str); - out_count += strlen(str); - if (out_count > 60) - { - printf ("\n"); - out_count = 0; - } - } - else - load_code (str); -} - - -/* Execute the current code as loaded. */ - -void -run_code() -{ - /* If no compile errors run the current code. */ - if (!had_error && did_gen) - { - if (compile_only) - { - printf ("@r\n"); - out_count = 0; - } - else - execute (); - } - - /* Reinitialize the code generation and machine. */ - if (did_gen) - init_gen(); - else - had_error = FALSE; -} - - -/* Output routines: Write a character CH to the standard output. - It keeps track of the number of characters output and may - break the output with a "\". Always used for numbers. */ - -void -out_char (ch) - int ch; -{ - if (ch == '\n') - { - out_col = 0; - putchar ('\n'); - } - else - { - out_col++; - if (out_col == line_size-1) - { - putchar ('\\'); - putchar ('\n'); - out_col = 1; - } - putchar (ch); - } -} - -/* Output routines: Write a character CH to the standard output. - It keeps track of the number of characters output and may - break the output with a "\". This one is for strings. - In POSIX bc, strings are not broken across lines. */ - -void -out_schar (ch) - int ch; -{ - if (ch == '\n') - { - out_col = 0; - putchar ('\n'); - } - else - { - if (!std_only) - { - out_col++; - if (out_col == line_size-1) - { - putchar ('\\'); - putchar ('\n'); - out_col = 1; - } - } - putchar (ch); - } -} - - -/* The following are "Symbol Table" routines for the parser. */ - -/* find_id returns a pointer to node in TREE that has the correct - ID. If there is no node in TREE with ID, NULL is returned. */ - -id_rec * -find_id (tree, id) - id_rec *tree; - char *id; -{ - int cmp_result; - - /* Check for an empty tree. */ - if (tree == NULL) - return NULL; - - /* Recursively search the tree. */ - cmp_result = strcmp (id, tree->id); - if (cmp_result == 0) - return tree; /* This is the item. */ - else if (cmp_result < 0) - return find_id (tree->left, id); - else - return find_id (tree->right, id); -} - - -/* insert_id_rec inserts a NEW_ID rec into the tree whose ROOT is - provided. insert_id_rec returns TRUE if the tree height from - ROOT down is increased otherwise it returns FALSE. This is a - recursive balanced binary tree insertion algorithm. */ - -int insert_id_rec (root, new_id) - id_rec **root; - id_rec *new_id; -{ - id_rec *A, *B; - - /* If root is NULL, this where it is to be inserted. */ - if (*root == NULL) - { - *root = new_id; - new_id->left = NULL; - new_id->right = NULL; - new_id->balance = 0; - return (TRUE); - } - - /* We need to search for a leaf. */ - if (strcmp (new_id->id, (*root)->id) < 0) - { - /* Insert it on the left. */ - if (insert_id_rec (&((*root)->left), new_id)) - { - /* The height increased. */ - (*root)->balance --; - - switch ((*root)->balance) - { - case 0: /* no height increase. */ - return (FALSE); - case -1: /* height increase. */ - return (FALSE); - case -2: /* we need to do a rebalancing act. */ - A = *root; - B = (*root)->left; - if (B->balance <= 0) - { - /* Single Rotate. */ - A->left = B->right; - B->right = A; - *root = B; - A->balance = 0; - B->balance = 0; - } - else - { - /* Double Rotate. */ - *root = B->right; - B->right = (*root)->left; - A->left = (*root)->right; - (*root)->left = B; - (*root)->right = A; - switch ((*root)->balance) - { - case -1: - A->balance = 1; - B->balance = 0; - break; - case 0: - A->balance = 0; - B->balance = 0; - break; - case 1: - A->balance = 0; - B->balance = -1; - break; - } - (*root)->balance = 0; - } - } - } - } - else - { - /* Insert it on the right. */ - if (insert_id_rec (&((*root)->right), new_id)) - { - /* The height increased. */ - (*root)->balance ++; - switch ((*root)->balance) - { - case 0: /* no height increase. */ - return (FALSE); - case 1: /* height increase. */ - return (FALSE); - case 2: /* we need to do a rebalancing act. */ - A = *root; - B = (*root)->right; - if (B->balance >= 0) - { - /* Single Rotate. */ - A->right = B->left; - B->left = A; - *root = B; - A->balance = 0; - B->balance = 0; - } - else - { - /* Double Rotate. */ - *root = B->left; - B->left = (*root)->right; - A->right = (*root)->left; - (*root)->left = A; - (*root)->right = B; - switch ((*root)->balance) - { - case -1: - A->balance = 0; - B->balance = 1; - break; - case 0: - A->balance = 0; - B->balance = 0; - break; - case 1: - A->balance = -1; - B->balance = 0; - break; - } - (*root)->balance = 0; - } - } - } - } - - /* If we fall through to here, the tree did not grow in height. */ - return (FALSE); -} - - -/* Initialize variables for the symbol table tree. */ - -void -init_tree() -{ - name_tree = NULL; - next_array = 1; - next_func = 1; - /* 0 => ibase, 1 => obase, 2 => scale, 3 => history, 4 => last. */ - next_var = 5; -} - - -/* Lookup routines for symbol table names. */ - -int -lookup (name, namekind) - char *name; - int namekind; -{ - id_rec *id; - - /* Warn about non-standard name. */ - if (strlen(name) != 1) - warn ("multiple letter name - %s", name); - - /* Look for the id. */ - id = find_id (name_tree, name); - if (id == NULL) - { - /* We need to make a new item. */ - id = (id_rec *) bc_malloc (sizeof (id_rec)); - id->id = strcopyof (name); - id->a_name = 0; - id->f_name = 0; - id->v_name = 0; - insert_id_rec (&name_tree, id); - } - - /* Return the correct value. */ - switch (namekind) - { - - case ARRAY: - /* ARRAY variable numbers are returned as negative numbers. */ - if (id->a_name != 0) - { - free (name); - return (-id->a_name); - } - id->a_name = next_array++; - a_names[id->a_name] = name; - if (id->a_name < MAX_STORE) - { - if (id->a_name >= a_count) - more_arrays (); - return (-id->a_name); - } - yyerror ("Too many array variables"); - exit (1); - - case FUNCT: - case FUNCTDEF: - if (id->f_name != 0) - { - free(name); - /* Check to see if we are redefining a math lib function. */ - if (use_math && namekind == FUNCTDEF && id->f_name <= 6) - id->f_name = next_func++; - return (id->f_name); - } - id->f_name = next_func++; - f_names[id->f_name] = name; - if (id->f_name < MAX_STORE) - { - if (id->f_name >= f_count) - more_functions (); - return (id->f_name); - } - yyerror ("Too many functions"); - exit (1); - - case SIMPLE: - if (id->v_name != 0) - { - free(name); - return (id->v_name); - } - id->v_name = next_var++; - v_names[id->v_name - 1] = name; - if (id->v_name <= MAX_STORE) - { - if (id->v_name >= v_count) - more_variables (); - return (id->v_name); - } - yyerror ("Too many variables"); - exit (1); - } - - yyerror ("End of util.c/lookup() reached. Please report this bug."); - exit (1); - /* 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 version information. */ -void -show_bc_version() -{ - printf("%s %s\n%s\n", PACKAGE, VERSION, BC_COPYRIGHT); -} - - -/* Print out the warranty information. */ - -void -warranty(prefix) - char *prefix; -{ - printf ("\n%s", prefix); - show_bc_version (); - printf ("\n" -" This program is free software; you can redistribute it and/or modify\n" -" it under the terms of the GNU General Public License as published by\n" -" the Free Software Foundation; either version 2 of the License , or\n" -" (at your option) any later version.\n\n" -" This program is distributed in the hope that it will be useful,\n" -" but WITHOUT ANY WARRANTY; without even the implied warranty of\n" -" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" -" GNU General Public License for more details.\n\n" -" You should have received a copy of the GNU General Public License\n" -" along with this program. If not, write to\n\n" -" The Free Software Foundation, Inc.\n" -" 59 Temple Place, Suite 330\n" -" Boston, MA 02111, 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 ("Number of vars = %ld\n", (long) MAX_STORE); -#ifdef OLD_EQ_OP - printf ("Old assignment operatiors are valid. (=-, =+, ...)\n"); -#endif -} - -/* bc_malloc will check the return value so all other places do not - have to do it! SIZE is the number of bytes to allocate. */ - -char * -bc_malloc (size) - int size; -{ - char *ptr; - - ptr = (char *) malloc (size); - if (ptr == NULL) - out_of_memory (); - - return ptr; -} - - -/* The following routines are error routines for various problems. */ - -/* Malloc could not get enought memory. */ - -void -out_of_memory() -{ - fprintf (stderr, "Fatal error: Out of memory for malloc.\n"); - exit (1); -} - - - -/* The standard yyerror routine. Built with variable number of argumnets. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -yyerror (char *str, ...) -#else -void -yyerror (str) - char *str; -#endif -#else -void -yyerror (str, va_alist) - char *str; -#endif -{ - char *name; - va_list args; - -#ifndef VARARGS - va_start (args, str); -#else - va_start (args); -#endif - if (is_std_in) - name = "(standard_in)"; - else - name = file_name; - fprintf (stderr,"%s %d: ",name,line_no); - vfprintf (stderr, str, args); - fprintf (stderr, "\n"); - had_error = TRUE; - va_end (args); -} - - -/* The routine to produce warnings about non-standard features - found during parsing. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -warn (char *mesg, ...) -#else -void -warn (mesg) - char *mesg; -#endif -#else -void -warn (mesg, va_alist) - char *mesg; -#endif -{ - char *name; - va_list args; - -#ifndef VARARGS - va_start (args, mesg); -#else - va_start (args); -#endif - if (std_only) - { - if (is_std_in) - name = "(standard_in)"; - else - name = file_name; - fprintf (stderr,"%s %d: ",name,line_no); - vfprintf (stderr, mesg, args); - fprintf (stderr, "\n"); - had_error = TRUE; - } - else - if (warn_not_std) - { - if (is_std_in) - name = "(standard_in)"; - else - name = file_name; - fprintf (stderr,"%s %d: (Warning) ",name,line_no); - vfprintf (stderr, mesg, args); - fprintf (stderr, "\n"); - } - va_end (args); -} - -/* Runtime error will print a message and stop the machine. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -rt_error (char *mesg, ...) -#else -void -rt_error (mesg) - char *mesg; -#endif -#else -void -rt_error (mesg, va_alist) - char *mesg; -#endif -{ - va_list args; - - fprintf (stderr, "Runtime error (func=%s, adr=%d): ", - f_names[pc.pc_func], pc.pc_addr); -#ifndef VARARGS - va_start (args, mesg); -#else - va_start (args); -#endif - vfprintf (stderr, mesg, args); - va_end (args); - - fprintf (stderr, "\n"); - runtime_error = TRUE; -} - - -/* A runtime warning tells of some action taken by the processor that - may change the program execution but was not enough of a problem - to stop the execution. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -rt_warn (char *mesg, ...) -#else -void -rt_warn (mesg) - char *mesg; -#endif -#else -void -rt_warn (mesg, va_alist) - char *mesg; -#endif -{ - va_list args; - - fprintf (stderr, "Runtime warning (func=%s, adr=%d): ", - f_names[pc.pc_func], pc.pc_addr); -#ifndef VARARGS - va_start (args, mesg); -#else - va_start (args); -#endif - vfprintf (stderr, mesg, args); - va_end (args); - - fprintf (stderr, "\n"); -} diff --git a/src/bin/bc/config.h b/src/bin/bc/config.h deleted file mode 100644 index 90057e9751..0000000000 --- a/src/bin/bc/config.h +++ /dev/null @@ -1,82 +0,0 @@ -/* config.h. Generated automatically by configure. */ -/* config.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define to empty if the keyword does not work. */ -/* #undef const */ - -/* Define if you don't have vprintf but do have _doprnt. */ -/* #undef HAVE_DOPRNT */ - -/* Define if you have the vprintf function. */ -#define HAVE_VPRINTF 1 - -/* Define if on MINIX. */ -/* #undef _MINIX */ - -/* Define if the system does not provide POSIX.1 features except - with this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define if you need to in order for stat and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define to `unsigned' if doesn't define. */ -/* #undef size_t */ - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if lex declares yytext as a char * by default, not a char[]. */ -#define YYTEXT_POINTER 1 - -/* VERSION number for DC target*/ -#define DC_VERSION "1.3" - -/* COPYRIGHT notice for DC target */ -#define DC_COPYRIGHT "Copyright 1994, 1997, 1998, 2000 Free Software Foundation, Inc." - -/* COPYRIGHT notice for BC target */ -#define BC_COPYRIGHT "Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc." - -/* Define to use the readline library. */ -/* #undef READLINE */ - -/* Define to use the BSD libedit library. */ -/* #undef LIBEDIT */ - -/* Define to `size_t' if and don't define. */ -/* #undef ptrdiff_t */ - -/* Define if you have the isgraph function. */ -#define HAVE_ISGRAPH 1 - -/* Define if you have the setvbuf function. */ -#define HAVE_SETVBUF 1 - -/* Define if you have the header file. */ -/* #undef HAVE_LIB_H */ - -/* Define if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDARG_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDDEF_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Name of package */ -#define PACKAGE "bc" - -/* Version number of package */ -#define VERSION "1.06" - diff --git a/src/bin/bc/dc/Jamfile b/src/bin/bc/dc/Jamfile deleted file mode 100644 index 786539e080..0000000000 --- a/src/bin/bc/dc/Jamfile +++ /dev/null @@ -1,12 +0,0 @@ -SubDir HAIKU_TOP src bin bc dc ; - -SubDirCcFlags -DHAVE_CONFIG_H ; -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) lib ] ; -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; -SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) h ] ; - -BinCommand dc : - dc.c misc.c eval.c stack.c array.c numeric.c string.c - : libbc.a - : dc.rdef ; - diff --git a/src/bin/bc/dc/array.c b/src/bin/bc/dc/array.c deleted file mode 100644 index d97f716c5d..0000000000 --- a/src/bin/bc/dc/array.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * implement arrays for dc - * - * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -/* This module is the only one that knows what arrays look like. */ - -#include "config.h" - -#include /* "dc-proto.h" wants this */ -#ifdef HAVE_STDLIB_H -/* get size_t definition from "almost ANSI" compiling environments. */ -#include -#endif -#include "dc.h" -#include "dc-proto.h" -#include "dc-regdef.h" - -/* what's most useful: quick access or sparse arrays? */ -/* I'll go with sparse arrays for now */ -struct dc_array { - int Index; - dc_data value; - struct dc_array *next; -}; - - -/* initialize the arrays */ -void -dc_array_init DC_DECLVOID() -{ -} - -/* store value into array_id[Index] */ -void -dc_array_set DC_DECLARG((array_id, Index, value)) - int array_id DC_DECLSEP - int Index DC_DECLSEP - dc_data value DC_DECLEND -{ - struct dc_array *cur; - struct dc_array *prev=NULL; - struct dc_array *newentry; - - cur = dc_get_stacked_array(array_id); - while (cur && cur->Index < Index){ - prev = cur; - cur = cur->next; - } - if (cur && cur->Index == Index){ - if (cur->value.dc_type == DC_NUMBER) - dc_free_num(&cur->value.v.number); - else if (cur->value.dc_type == DC_STRING) - dc_free_str(&cur->value.v.string); - else - dc_garbage(" in array", array_id); - cur->value = value; - }else{ - newentry = dc_malloc(sizeof *newentry); - newentry->Index = Index; - newentry->value = value; - newentry->next = cur; - if (prev) - prev->next = newentry; - else - dc_set_stacked_array(array_id, newentry); - } -} - -/* retrieve a dup of a value from array_id[Index] */ -/* A zero value is returned if the specified value is unintialized. */ -dc_data -dc_array_get DC_DECLARG((array_id, Index)) - int array_id DC_DECLSEP - int Index DC_DECLEND -{ - struct dc_array *cur; - - for (cur=dc_get_stacked_array(array_id); cur; cur=cur->next) - if (cur->Index == Index) - return dc_dup(cur->value); - return dc_int2data(0); -} - -/* free an array chain */ -void -dc_array_free DC_DECLARG((a_head)) - struct dc_array *a_head DC_DECLEND -{ - struct dc_array *cur; - struct dc_array *next; - - for (cur=a_head; cur; cur=next) { - next = cur->next; - if (cur->value.dc_type == DC_NUMBER) - dc_free_num(&cur->value.v.number); - else if (cur->value.dc_type == DC_STRING) - dc_free_str(&cur->value.v.string); - else - dc_garbage("in stack", -1); - free(cur); - } -} diff --git a/src/bin/bc/dc/dc-proto.h b/src/bin/bc/dc/dc-proto.h deleted file mode 100644 index f0ac28bfaf..0000000000 --- a/src/bin/bc/dc/dc-proto.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * prototypes of all externally visible dc functions - * - * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -extern const char *dc_str2charp DC_PROTO((dc_str)); -extern const char *dc_system DC_PROTO((const char *)); -extern void *dc_malloc DC_PROTO((size_t)); -extern struct dc_array *dc_get_stacked_array DC_PROTO((int)); - -extern void dc_array_set DC_PROTO((int, int, dc_data)); -extern void dc_array_free DC_PROTO((struct dc_array *)); -extern void dc_array_init DC_PROTO((void)); -extern void dc_binop DC_PROTO((int (*)(dc_num, dc_num, int, dc_num *), int)); -extern void dc_binop2 DC_PROTO((int (*)(dc_num, dc_num, int, - dc_num *, dc_num *), int)); -extern void dc_triop DC_PROTO((int (*)(dc_num, dc_num, dc_num, int, - dc_num *), int)); -extern void dc_clear_stack DC_PROTO((void)); -extern void dc_dump_num(dc_num, dc_discard); -extern void dc_free_num DC_PROTO((dc_num *)); -extern void dc_free_str DC_PROTO((dc_str *)); -extern void dc_garbage DC_PROTO((const char *, int)); -extern void dc_math_init DC_PROTO((void)); -extern void dc_memfail DC_PROTO((void)); -extern void dc_out_num DC_PROTO((dc_num, int, dc_newline, dc_discard)); -extern void dc_out_str DC_PROTO((dc_str, dc_newline, dc_discard)); -extern void dc_print DC_PROTO((dc_data, int, dc_newline, dc_discard)); -extern void dc_printall DC_PROTO((int)); -extern void dc_push DC_PROTO((dc_data)); -extern void dc_register_init DC_PROTO((void)); -extern void dc_register_push DC_PROTO((int, dc_data)); -extern void dc_register_set DC_PROTO((int, dc_data)); -extern void dc_set_stacked_array DC_PROTO((int, struct dc_array *)); -extern void dc_show_id DC_PROTO((FILE *, int, const char *)); -extern void dc_string_init DC_PROTO((void)); - -extern int dc_cmpop DC_PROTO((void)); -extern int dc_compare DC_PROTO((dc_num, dc_num)); -extern int dc_evalfile DC_PROTO((FILE *)); -extern int dc_evalstr DC_PROTO((dc_data)); -extern int dc_num2int DC_PROTO((dc_num, dc_discard)); -extern int dc_numlen DC_PROTO((dc_num)); -extern int dc_pop DC_PROTO((dc_data *)); -extern int dc_register_get DC_PROTO((int, dc_data *)); -extern int dc_register_pop DC_PROTO((int, dc_data *)); -extern int dc_tell_length DC_PROTO((dc_data, dc_discard)); -extern int dc_tell_scale DC_PROTO((dc_num, dc_discard)); -extern int dc_tell_stackdepth DC_PROTO((void)); -extern int dc_top_of_stack DC_PROTO((dc_data *)); - -extern size_t dc_strlen DC_PROTO((dc_str)); - -extern dc_data dc_array_get DC_PROTO((int, int)); -extern dc_data dc_dup DC_PROTO((dc_data)); -extern dc_data dc_dup_num DC_PROTO((dc_num)); -extern dc_data dc_dup_str DC_PROTO((dc_str)); -extern dc_data dc_getnum DC_PROTO((int (*)(void), int, int *)); -extern dc_data dc_int2data DC_PROTO((int)); -extern dc_data dc_makestring DC_PROTO((const char *, size_t)); -extern dc_data dc_readstring DC_PROTO((FILE *, int , int)); - -extern int dc_add DC_PROTO((dc_num, dc_num, int, dc_num *)); -extern int dc_div DC_PROTO((dc_num, dc_num, int, dc_num *)); -extern int dc_divrem DC_PROTO((dc_num, dc_num, int, dc_num *, dc_num *)); -extern int dc_exp DC_PROTO((dc_num, dc_num, int, dc_num *)); -extern int dc_modexp DC_PROTO((dc_num, dc_num, dc_num, int, dc_num *)); -extern int dc_mul DC_PROTO((dc_num, dc_num, int, dc_num *)); -extern int dc_rem DC_PROTO((dc_num, dc_num, int, dc_num *)); -extern int dc_sub DC_PROTO((dc_num, dc_num, int, dc_num *)); -extern int dc_sqrt DC_PROTO((dc_num, int, dc_num *)); diff --git a/src/bin/bc/dc/dc-regdef.h b/src/bin/bc/dc/dc-regdef.h deleted file mode 100644 index 540268c196..0000000000 --- a/src/bin/bc/dc/dc-regdef.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * definitions for dc's "register" declarations - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -#ifdef HAVE_LIMITS_H -# include /* UCHAR_MAX */ -#endif - -/* determine how many register stacks there are */ -#ifndef DC_REGCOUNT -# ifndef UCHAR_MAX -# define DC_REGCOUNT 256 -# else -# define DC_REGCOUNT (UCHAR_MAX+1) -# endif -#endif /* not DC_REGCOUNT */ - -/* efficiency hack for masking arbritrary integers to 0..(DC_REGCOUNT-1) */ -#if (DC_REGCOUNT & (DC_REGCOUNT-1)) == 0 /* DC_REGCOUNT is power of 2 */ -# define regmap(r) ((r) & (DC_REGCOUNT-1)) -#else -# define regmap(r) ((r) % DC_REGCOUNT) -#endif diff --git a/src/bin/bc/dc/dc.c b/src/bin/bc/dc/dc.c deleted file mode 100644 index a72644ce87..0000000000 --- a/src/bin/bc/dc/dc.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * implement the "dc" Desk Calculator language. - * - * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -/* Written with strong hiding of implementation details - * in their own specialized modules. - */ -/* This module contains the argument processing/main functions. - */ - -#include "config.h" - -#include -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_STRING_H -# include -#else -# ifdef HAVE_STRINGS_H -# include -# endif -#endif -#include -#include "dc.h" -#include "dc-proto.h" - -#ifndef EXIT_SUCCESS /* C89 */ -# define EXIT_SUCCESS 0 -#endif -#ifndef EXIT_FAILURE /* C89 */ -# define EXIT_FAILURE 1 -#endif - -const char *progname; /* basename of program invocation */ - -static void -bug_report_info DC_DECLVOID() -{ - printf("Email bug reports to: bug-dc@gnu.org .\n"); -} - -static void -show_version DC_DECLVOID() -{ - printf("dc (GNU %s %s) %s\n", PACKAGE, VERSION, DC_VERSION); - printf("\n%s\n\ -This is free software; see the source for copying conditions. There is NO\n\ -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n\ -to the extent permitted by law.\n", DC_COPYRIGHT); -} - -/* your generic usage function */ -static void -usage DC_DECLARG((f)) - FILE *f DC_DECLEND -{ - fprintf(f, "\ -Usage: %s [OPTION] [file ...]\n\ - -e, --expression=EXPR evaluate expression\n\ - -f, --file=FILE evaluate contents of file\n\ - -h, --help display this help and exit\n\ - -V, --version output version information and exit\n\ -\n\ -", progname); - bug_report_info(); -} - -/* returns a pointer to one past the last occurance of c in s, - * or s if c does not occur in s. - */ -static char * -r1bindex DC_DECLARG((s, c)) - char *s DC_DECLSEP - int c DC_DECLEND -{ - char *p = strrchr(s, c); - - if (!p) - return s; - return p + 1; -} - -static void -try_file(const char *filename) -{ - FILE *input; - - if (strcmp(filename, "-") == 0) { - input = stdin; - } else if ( !(input=fopen(filename, "r")) ) { - fprintf(stderr, "Could not open file "); - perror(filename); - exit(EXIT_FAILURE); - } - if (dc_evalfile(input)) - exit(EXIT_FAILURE); - if (input != stdin) - fclose(input); -} - - -int -main DC_DECLARG((argc, argv)) - int argc DC_DECLSEP - char **argv DC_DECLEND -{ - static struct option const long_opts[] = { - {"expression", required_argument, NULL, 'e'}, - {"file", required_argument, NULL, 'f'}, - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'V'}, - {NULL, 0, NULL, 0} - }; - int did_eval = 0; - int c; - - progname = r1bindex(*argv, '/'); -#ifdef HAVE_SETVBUF - /* attempt to simplify interaction with applications such as emacs */ - (void) setvbuf(stdout, NULL, _IOLBF, 0); -#endif - dc_math_init(); - dc_string_init(); - dc_register_init(); - dc_array_init(); - - while ((c = getopt_long(argc, argv, "hVe:f:", long_opts, (int *)0)) != EOF) { - switch (c) { - case 'e': - { dc_data string = dc_makestring(optarg, strlen(optarg)); - if (dc_evalstr(string)) - return EXIT_SUCCESS; - dc_free_str(&string.v.string); - did_eval = 1; - } - break; - case 'f': - try_file(optarg); - did_eval = 1; - break; - case 'h': - usage(stdout); - return EXIT_SUCCESS; - case 'V': - show_version(); - return EXIT_SUCCESS; - default: - usage(stderr); - return EXIT_FAILURE; - } - } - - for (; optind < argc; ++optind) { - try_file(argv[optind]); - did_eval = 1; - } - if (!did_eval) { - /* if no -e commands and no command files, then eval stdin */ - if (dc_evalfile(stdin)) - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} diff --git a/src/bin/bc/dc/dc.h b/src/bin/bc/dc/dc.h deleted file mode 100644 index 3300f44426..0000000000 --- a/src/bin/bc/dc/dc.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Header file for dc routines - * - * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -#ifndef DC_DEFS_H -#define DC_DEFS_H - -/* 'I' is a command, and bases 17 and 18 are quite - * unusual, so we limit ourselves to bases 2 to 16 - */ -#define DC_IBASE_MAX 16 - -#define DC_SUCCESS 0 -#define DC_DOMAIN_ERROR 1 -#define DC_FAIL 2 /* generic failure */ - - -#ifndef __STDC__ -# define DC_PROTO(x) () -# define DC_DECLVOID() () -# define DC_DECLARG(arglist) arglist -# define DC_DECLSEP ; -# define DC_DECLEND ; -#else /* __STDC__ */ -# define DC_PROTO(x) x -# define DC_DECLVOID() (void) -# define DC_DECLARG(arglist) ( -# define DC_DECLSEP , -# define DC_DECLEND ) -#endif /* __STDC__ */ - - -typedef enum {DC_TOSS, DC_KEEP} dc_discard; -typedef enum {DC_NONL, DC_WITHNL} dc_newline; - - -/* type discriminant for dc_data */ -typedef enum {DC_UNINITIALIZED, DC_NUMBER, DC_STRING} dc_value_type; - -/* only numeric.c knows what dc_num's *really* look like */ -typedef struct dc_number *dc_num; - -/* only string.c knows what dc_str's *really* look like */ -typedef struct dc_string *dc_str; - - -/* except for the two implementation-specific modules, all - * dc functions only know of this one generic type of object - */ -typedef struct { - dc_value_type dc_type; /* discriminant for union */ - union { - dc_num number; - dc_str string; - } v; -} dc_data; - - -/* This is dc's only global variable: */ -extern const char *progname; /* basename of program invocation */ - -#endif /* not DC_DEFS_H */ diff --git a/src/bin/bc/dc/dc.rdef b/src/bin/bc/dc/dc.rdef deleted file mode 100644 index 4164219d0d..0000000000 --- a/src/bin/bc/dc/dc.rdef +++ /dev/null @@ -1,11 +0,0 @@ -resource app_version -{ - major = 1, - middle = 3, - minor = 0, - variety = 5, - internal = 0, - short_info = "1.3", - long_info = "1.3 ©2000 The Free Software Foundation" -}; - diff --git a/src/bin/bc/dc/eval.c b/src/bin/bc/dc/eval.c deleted file mode 100644 index 21592d932a..0000000000 --- a/src/bin/bc/dc/eval.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * evaluate the dc language, from a FILE* or a string - * - * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -/* This is the only module which knows about the dc input language */ - -#include "config.h" - -#include -#ifdef HAVE_STRING_H -# include /* memchr */ -#else -# ifdef HAVE_MEMORY_H -# include /* memchr, maybe */ -# else -# ifdef HAVE_STRINGS_H -# include /* memchr, maybe */ -# endif -#endif -#endif -#include "dc.h" -#include "dc-proto.h" - -typedef enum {DC_FALSE, DC_TRUE} dc_boolean; - -typedef enum { - DC_OKAY = DC_SUCCESS, /* no further intervention needed for this command */ - DC_EATONE, /* caller needs to eat the lookahead char */ - DC_QUIT, /* quit out of unwind_depth levels of evaluation */ - - /* with the following return values, the caller does not have to - * fret about stdin_lookahead's value - */ - DC_INT, /* caller needs to parse a dc_num from input stream */ - DC_STR, /* caller needs to parse a dc_str from input stream */ - DC_SYSTEM, /* caller needs to run a system() on next input line */ - DC_COMMENT, /* caller needs to skip to the next input line */ - DC_NEGCMP, /* caller needs to re-call dc_func() with `negcmp' set */ - - DC_EOF_ERROR /* unexpected end of input; abort current eval */ -} dc_status; - -static int dc_ibase=10; /* input base, 2 <= dc_ibase <= DC_IBASE_MAX */ -static int dc_obase=10; /* output base, 2 <= dc_obase */ -static int dc_scale=0; /* scale (see user documentaton) */ - -/* for Quitting evaluations */ -static int unwind_depth=0; - -/* if true, active Quit will not exit program */ -static dc_boolean unwind_noexit=DC_FALSE; - -/* - * Used to synchronize lookahead on stdin for '?' command. - * If set to EOF then lookahead is used up. - */ -static int stdin_lookahead=EOF; - - -/* input_fil and input_str are passed as arguments to dc_getnum */ - -/* used by the input_* functions: */ -static FILE *input_fil_fp; -static const char *input_str_string; - -/* Since we have a need for two characters of pushback, and - * ungetc() only guarantees one, we place the second pushback here - */ -static int input_pushback; - -/* passed as an argument to dc_getnum */ -static int -input_fil DC_DECLVOID() -{ - if (input_pushback != EOF){ - int c = input_pushback; - input_pushback = EOF; - return c; - } - return getc(input_fil_fp); -} - -/* passed as an argument to dc_getnum */ -static int -input_str DC_DECLVOID() -{ - if (!*input_str_string) - return EOF; - return *input_str_string++; -} - - - -/* takes a string and evals it; frees the string when done */ -/* Wrapper around dc_evalstr to avoid duplicating the free call - * at all possible return points. - */ -static int -dc_eval_and_free_str DC_DECLARG((string)) - dc_data string DC_DECLEND -{ - dc_status status; - - status = dc_evalstr(string); - if (string.dc_type == DC_STRING) - dc_free_str(&string.v.string); - return status; -} - - -/* dc_func does the grunt work of figuring out what each input - * character means; used by both dc_evalstr and dc_evalfile - * - * c -> the "current" input character under consideration - * peekc -> the lookahead input character - * negcmp -> negate comparison test (for <,=,> commands) - */ -static dc_status -dc_func DC_DECLARG((c, peekc, negcmp)) - int c DC_DECLSEP - int peekc DC_DECLSEP - int negcmp DC_DECLEND -{ - /* we occasionally need these for temporary data */ - /* Despite the GNU coding standards, it is much easier - * to have these declared once here, since this function - * is just one big switch statement. - */ - dc_data datum; - int tmpint; - - switch (c){ - case '_': case '.': - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - case '8': case '9': case 'A': case 'B': - case 'C': case 'D': case 'E': case 'F': - return DC_INT; - case ' ': - case '\t': - case '\n': - /* standard command separators */ - break; - - case '+': /* add top two stack elements */ - dc_binop(dc_add, dc_scale); - break; - case '-': /* subtract top two stack elements */ - dc_binop(dc_sub, dc_scale); - break; - case '*': /* multiply top two stack elements */ - dc_binop(dc_mul, dc_scale); - break; - case '/': /* divide top two stack elements */ - dc_binop(dc_div, dc_scale); - break; - case '%': - /* take the remainder from division of the top two stack elements */ - dc_binop(dc_rem, dc_scale); - break; - case '~': - /* Do division on the top two stack elements. Return the - * quotient as next-to-top of stack and the remainder as - * top-of-stack. - */ - dc_binop2(dc_divrem, dc_scale); - break; - case '|': - /* Consider the top three elements of the stack as (base, exp, mod), - * where mod is top-of-stack, exp is next-to-top, and base is - * second-from-top. Mod must be non-zero, exp must be non-negative, - * and all three must be integers. Push the result of raising - * base to the exp power, reduced modulo mod. If we had base in - * register b, exp in register e, and mod in register m then this - * is conceptually equivalent to "lble^lm%", but it is implemented - * in a more efficient manner, and can handle arbritrarily large - * values for exp. - */ - dc_triop(dc_modexp, dc_scale); - break; - case '^': /* exponientiation of the top two stack elements */ - dc_binop(dc_exp, dc_scale); - break; - case '<': - /* eval register named by peekc if - * less-than holds for top two stack elements - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if ( (dc_cmpop() < 0) == !negcmp ) - if (dc_register_get(peekc, &datum) == DC_SUCCESS) - if (dc_eval_and_free_str(datum) == DC_QUIT) - return DC_QUIT; - return DC_EATONE; - case '=': - /* eval register named by peekc if - * equal-to holds for top two stack elements - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if ( (dc_cmpop() == 0) == !negcmp ) - if (dc_register_get(peekc, &datum) == DC_SUCCESS) - if (dc_eval_and_free_str(datum) == DC_QUIT) - return DC_QUIT; - return DC_EATONE; - case '>': - /* eval register named by peekc if - * greater-than holds for top two stack elements - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if ( (dc_cmpop() > 0) == !negcmp ) - if (dc_register_get(peekc, &datum) == DC_SUCCESS) - if (dc_eval_and_free_str(datum) == DC_QUIT) - return DC_QUIT; - return DC_EATONE; - case '?': /* read a line from standard-input and eval it */ - if (stdin_lookahead != EOF){ - ungetc(stdin_lookahead, stdin); - stdin_lookahead = EOF; - } - if (dc_eval_and_free_str(dc_readstring(stdin, '\n', '\n')) == DC_QUIT) - return DC_QUIT; - return DC_OKAY; - case '[': /* read to balancing ']' into a dc_str */ - return DC_STR; - case '!': /* read to newline and call system() on resulting string */ - if (peekc == '<' || peekc == '=' || peekc == '>') - return DC_NEGCMP; - return DC_SYSTEM; - case '#': /* comment; skip remainder of current line */ - return DC_COMMENT; - - case 'a': /* Convert top of stack to an ascii character. */ - if (dc_pop(&datum) == DC_SUCCESS){ - char tmps; - if (datum.dc_type == DC_NUMBER){ - tmps = (char) dc_num2int(datum.v.number, DC_TOSS); - }else if (datum.dc_type == DC_STRING){ - tmps = *dc_str2charp(datum.v.string); - dc_free_str(&datum.v.string); - }else{ - dc_garbage("at top of stack", -1); - } - dc_push(dc_makestring(&tmps, 1)); - } - break; - case 'c': /* clear whole stack */ - dc_clear_stack(); - break; - case 'd': /* duplicate the datum on the top of stack */ - if (dc_top_of_stack(&datum) == DC_SUCCESS) - dc_push(dc_dup(datum)); - break; - case 'f': /* print list of all stack items */ - dc_printall(dc_obase); - break; - case 'i': /* set input base to value on top of stack */ - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = 0; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TOSS); - if ( ! (2 <= tmpint && tmpint <= DC_IBASE_MAX) ) - fprintf(stderr, - "%s: input base must be a number \ -between 2 and %d (inclusive)\n", - progname, DC_IBASE_MAX); - else - dc_ibase = tmpint; - } - break; - case 'k': /* set scale to value on top of stack */ - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = -1; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TOSS); - if ( ! (tmpint >= 0) ) - fprintf(stderr, - "%s: scale must be a nonnegative number\n", - progname); - else - dc_scale = tmpint; - } - break; - case 'l': /* "load" -- push value on top of register stack named - * by peekc onto top of evaluation stack; does not - * modify the register stack - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_register_get(peekc, &datum) == DC_SUCCESS) - dc_push(datum); - return DC_EATONE; - case 'n': /* print the value popped off of top-of-stack; - * do not add a trailing newline - */ - if (dc_pop(&datum) == DC_SUCCESS) - dc_print(datum, dc_obase, DC_NONL, DC_TOSS); - break; - case 'o': /* set output base to value on top of stack */ - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = 0; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TOSS); - if ( ! (tmpint > 1) ) - fprintf(stderr, - "%s: output base must be a number greater than 1\n", - progname); - else - dc_obase = tmpint; - } - break; - case 'p': /* print the datum on the top of stack, - * with a trailing newline - */ - if (dc_top_of_stack(&datum) == DC_SUCCESS) - dc_print(datum, dc_obase, DC_WITHNL, DC_KEEP); - break; - case 'q': /* quit two levels of evaluation, posibly exiting program */ - unwind_depth = 1; /* the return below is the first level of returns */ - unwind_noexit = DC_FALSE; - return DC_QUIT; - case 'r': /* rotate (swap) the top two elements on the stack - */ - if (dc_pop(&datum) == DC_SUCCESS) { - dc_data datum2; - int two_status; - two_status = dc_pop(&datum2); - dc_push(datum); - if (two_status == DC_SUCCESS) - dc_push(datum2); - } - break; - case 's': /* "store" -- replace top of register stack named - * by peekc with the value popped from the top - * of the evaluation stack - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_pop(&datum) == DC_SUCCESS) - dc_register_set(peekc, datum); - return DC_EATONE; - case 'v': /* replace top of stack with its square root */ - if (dc_pop(&datum) == DC_SUCCESS){ - dc_num tmpnum; - if (datum.dc_type != DC_NUMBER){ - fprintf(stderr, - "%s: square root of nonnumeric attempted\n", - progname); - }else if (dc_sqrt(datum.v.number, dc_scale, &tmpnum) == DC_SUCCESS){ - dc_free_num(&datum.v.number); - datum.v.number = tmpnum; - dc_push(datum); - } - } - break; - case 'x': /* eval the datum popped from top of stack */ - if (dc_pop(&datum) == DC_SUCCESS){ - if (datum.dc_type == DC_STRING){ - if (dc_eval_and_free_str(datum) == DC_QUIT) - return DC_QUIT; - }else if (datum.dc_type == DC_NUMBER){ - dc_push(datum); - }else{ - dc_garbage("at top of stack", -1); - } - } - break; - case 'z': /* push the current stack depth onto the top of stack */ - dc_push(dc_int2data(dc_tell_stackdepth())); - break; - - case 'I': /* push the current input base onto the stack */ - dc_push(dc_int2data(dc_ibase)); - break; - case 'K': /* push the current scale onto the stack */ - dc_push(dc_int2data(dc_scale)); - break; - case 'L': /* pop a value off of register stack named by peekc - * and push it onto the evaluation stack - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_register_pop(peekc, &datum) == DC_SUCCESS) - dc_push(datum); - return DC_EATONE; - case 'O': /* push the current output base onto the stack */ - dc_push(dc_int2data(dc_obase)); - break; - case 'P': - /* Pop the value off the top of a stack. If it is - * a number, dump out the integer portion of its - * absolute value as a "base UCHAR_MAX+1" byte stream; - * if it is a string, just print it. - * In either case, do not append a trailing newline. - */ - if (dc_pop(&datum) == DC_SUCCESS){ - if (datum.dc_type == DC_NUMBER) - dc_dump_num(datum.v.number, DC_TOSS); - else if (datum.dc_type == DC_STRING) - dc_out_str(datum.v.string, DC_NONL, DC_TOSS); - else - dc_garbage("at top of stack", -1); - } - break; - case 'Q': /* quit out of top-of-stack nested evals; - * pops value from stack; - * does not exit program (stops short if necessary) - */ - if (dc_pop(&datum) == DC_SUCCESS){ - unwind_depth = 0; - unwind_noexit = DC_TRUE; - if (datum.dc_type == DC_NUMBER) - unwind_depth = dc_num2int(datum.v.number, DC_TOSS); - if (unwind_depth-- > 0) - return DC_QUIT; - unwind_depth = 0; /* paranoia */ - fprintf(stderr, - "%s: Q command requires a number >= 1\n", - progname); - } - break; -#if 0 - case 'R': /* pop a value off of the evaluation stack,; - * rotate the top - remaining stack elements that many - * places forward (negative numbers mean rotate - * backward). - */ - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = 0; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TOSS); - dc_stack_rotate(tmpint); - } - break; -#endif - case 'S': /* pop a value off of the evaluation stack - * and push it onto the register stack named by peekc - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_pop(&datum) == DC_SUCCESS) - dc_register_push(peekc, datum); - return DC_EATONE; - case 'X': /* replace the number on top-of-stack with its scale factor */ - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = 0; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_tell_scale(datum.v.number, DC_TOSS); - dc_push(dc_int2data(tmpint)); - } - break; - case 'Z': /* replace the datum on the top-of-stack with its length */ - if (dc_pop(&datum) == DC_SUCCESS) - dc_push(dc_int2data(dc_tell_length(datum, DC_TOSS))); - break; - - case ':': /* store into array */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = -1; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TOSS); - if (dc_pop(&datum) == DC_SUCCESS){ - if (tmpint < 0) - fprintf(stderr, - "%s: array index must be a nonnegative integer\n", - progname); - else - dc_array_set(peekc, tmpint, datum); - } - } - return DC_EATONE; - case ';': /* retreive from array */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = -1; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TOSS); - if (tmpint < 0) - fprintf(stderr, - "%s: array index must be a nonnegative integer\n", - progname); - else - dc_push(dc_array_get(peekc, tmpint)); - } - return DC_EATONE; - - default: /* What did that user mean? */ - fprintf(stderr, "%s: ", progname); - dc_show_id(stdout, c, " unimplemented\n"); - break; - } - return DC_OKAY; -} - - -/* takes a string and evals it */ -int -dc_evalstr DC_DECLARG((string)) - dc_data string DC_DECLEND -{ - const char *s; - const char *end; - const char *p; - size_t len; - int c; - int peekc; - int count; - int negcmp; - int next_negcmp = 0; - - if (string.dc_type != DC_STRING){ - fprintf(stderr, - "%s: eval called with non-string argument\n", - progname); - return DC_OKAY; - } - s = dc_str2charp(string.v.string); - end = s + dc_strlen(string.v.string); - while (s < end){ - c = *(const unsigned char *)s++; - peekc = EOF; - if (s < end) - peekc = *(const unsigned char *)s; - negcmp = next_negcmp; - next_negcmp = 0; - switch (dc_func(c, peekc, negcmp)){ - case DC_OKAY: - break; - case DC_EATONE: - if (peekc != EOF) - ++s; - break; - case DC_QUIT: - if (unwind_depth > 0){ - --unwind_depth; - return DC_QUIT; - } - return DC_OKAY; - - case DC_INT: - input_str_string = s - 1; - dc_push(dc_getnum(input_str, dc_ibase, &peekc)); - s = input_str_string; - if (peekc != EOF) - --s; - break; - case DC_STR: - count = 1; - for (p=s; p0; ++p) - if (*p == ']') - --count; - else if (*p == '[') - ++count; - len = p - s; - dc_push(dc_makestring(s, len-1)); - s = p; - break; - case DC_SYSTEM: - s = dc_system(s); - case DC_COMMENT: - s = memchr(s, '\n', (size_t)(end-s)); - if (!s) - s = end; - else - ++s; - break; - case DC_NEGCMP: - next_negcmp = 1; - break; - - case DC_EOF_ERROR: - fprintf(stderr, "%s: unexpected EOS\n", progname); - return DC_OKAY; - } - } - return DC_OKAY; -} - - -/* This is the main function of the whole DC program. - * Reads the file described by fp, calls dc_func to do - * the dirty work, and takes care of dc_func's shortcomings. - */ -int -dc_evalfile DC_DECLARG((fp)) - FILE *fp DC_DECLEND -{ - int c; - int peekc; - int negcmp; - int next_negcmp = 0; - dc_data datum; - - stdin_lookahead = EOF; - for (c=getc(fp); c!=EOF; c=peekc){ - peekc = getc(fp); - /* - * The following if() is the only place where ``stdin_lookahead'' - * might be set to other than EOF: - */ - if (fp == stdin) - stdin_lookahead = peekc; - negcmp = next_negcmp; - next_negcmp = 0; - switch (dc_func(c, peekc, negcmp)){ - case DC_OKAY: - if (stdin_lookahead != peekc && fp == stdin) - peekc = getc(fp); - break; - case DC_EATONE: - peekc = getc(fp); - break; - case DC_QUIT: - if (unwind_noexit != DC_TRUE) - return DC_SUCCESS; - fprintf(stderr, - "%s: Q command argument exceeded string execution depth\n", - progname); - if (stdin_lookahead != peekc && fp == stdin) - peekc = getc(fp); - break; - - case DC_INT: - input_fil_fp = fp; - input_pushback = c; - ungetc(peekc, fp); - dc_push(dc_getnum(input_fil, dc_ibase, &peekc)); - break; - case DC_STR: - ungetc(peekc, fp); - datum = dc_readstring(fp, '[', ']'); - dc_push(datum); - peekc = getc(fp); - break; - case DC_SYSTEM: - ungetc(peekc, fp); - datum = dc_readstring(stdin, '\n', '\n'); - (void)dc_system(dc_str2charp(datum.v.string)); - dc_free_str(&datum.v.string); - peekc = getc(fp); - break; - case DC_COMMENT: - while (peekc!=EOF && peekc!='\n') - peekc = getc(fp); - if (peekc != EOF) - peekc = getc(fp); - break; - case DC_NEGCMP: - next_negcmp = 1; - break; - - case DC_EOF_ERROR: - fprintf(stderr, "%s: unexpected EOF\n", progname); - return DC_FAIL; - } - } - return DC_SUCCESS; -} diff --git a/src/bin/bc/dc/misc.c b/src/bin/bc/dc/misc.c deleted file mode 100644 index fa94de12de..0000000000 --- a/src/bin/bc/dc/misc.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * misc. functions for the "dc" Desk Calculator language. - * - * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -/* This module contains miscelaneous functions that have no - * special knowledge of any private data structures. - * They could all be moved to their own separate modules, but - * are agglomerated here for convenience. - */ - -#include "config.h" - -#include -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_STRING_H -# include -#else -# ifdef HAVE_STRINGS_H -# include -# endif -#endif -#include -#ifndef isgraph -# ifndef HAVE_ISGRAPH -# define isgraph isprint -# endif -#endif -#include -#include "dc.h" -#include "dc-proto.h" - -#ifndef EXIT_FAILURE /* C89 */ -# define EXIT_FAILURE 1 -#endif - - -/* print an "out of memory" diagnostic and exit program */ -void -dc_memfail DC_DECLVOID() -{ - fprintf(stderr, "%s: out of memory\n", progname); - exit(EXIT_FAILURE); -} - -/* malloc or die */ -void * -dc_malloc DC_DECLARG((len)) - size_t len DC_DECLEND -{ - void *result = malloc(len); - - if (!result) - dc_memfail(); - return result; -} - - -/* print the id in a human-understandable form - * fp is the output stream to place the output on - * id is the name of the register (or command) to be printed - * suffix is a modifier (such as "stack") to be printed - */ -void -dc_show_id DC_DECLARG((fp, id, suffix)) - FILE *fp DC_DECLSEP - int id DC_DECLSEP - const char *suffix DC_DECLEND -{ - if (isgraph(id)) - fprintf(fp, "'%c' (%#o)%s", id, id, suffix); - else - fprintf(fp, "%#o%s", id, suffix); -} - - -/* report that corrupt data has been detected; - * use the msg and regid (if nonnegative) to give information - * about where the garbage was found, - * - * will abort() so that a debugger might be used to help find - * the bug - */ -/* If this routine is called, then there is a bug in the code; - * i.e. it is _not_ a data or user error - */ -void -dc_garbage DC_DECLARG((msg, regid)) - const char *msg DC_DECLSEP - int regid DC_DECLEND -{ - if (regid < 0) { - fprintf(stderr, "%s: garbage %s\n", progname, msg); - } else { - fprintf(stderr, "%s:%s register ", progname, msg); - dc_show_id(stderr, regid, " is garbage\n"); - } - abort(); -} - - -/* call system() with the passed string; - * if the string contains a newline, terminate the string - * there before calling system. - * Return a pointer to the first unused character in the string - * (i.e. past the '\n' if there was one, to the '\0' otherwise). - */ -const char * -dc_system DC_DECLARG((s)) - const char *s DC_DECLEND -{ - const char *p; - char *tmpstr; - size_t len; - - p = strchr(s, '\n'); - if (p) { - len = p - s; - tmpstr = dc_malloc(len + 1); - strncpy(tmpstr, s, len); - tmpstr[len] = '\0'; - system(tmpstr); - free(tmpstr); - return p + 1; - } - system(s); - return s + strlen(s); -} - - -/* print out the indicated value */ -void -dc_print DC_DECLARG((value, obase, newline_p, discard_p)) - dc_data value DC_DECLSEP - int obase DC_DECLSEP - dc_newline newline_p DC_DECLSEP - dc_discard discard_p DC_DECLEND -{ - if (value.dc_type == DC_NUMBER) { - dc_out_num(value.v.number, obase, newline_p, discard_p); - } else if (value.dc_type == DC_STRING) { - dc_out_str(value.v.string, newline_p, discard_p); - } else { - dc_garbage("in data being printed", -1); - } -} - -/* return a duplicate of the passed value, regardless of type */ -dc_data -dc_dup DC_DECLARG((value)) - dc_data value DC_DECLEND -{ - if (value.dc_type!=DC_NUMBER && value.dc_type!=DC_STRING) - dc_garbage("in value being duplicated", -1); - if (value.dc_type == DC_NUMBER) - return dc_dup_num(value.v.number); - /*else*/ - return dc_dup_str(value.v.string); -} diff --git a/src/bin/bc/dc/numeric.c b/src/bin/bc/dc/numeric.c deleted file mode 100644 index 6086be544f..0000000000 --- a/src/bin/bc/dc/numeric.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * interface dc to the bc numeric routines - * - * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -/* This should be the only module that knows the internals of type dc_num */ -/* In this particular implementation we just slather out some glue and - * make use of bc's numeric routines. - */ - -#include "config.h" - -#include -#include -#ifdef HAVE_LIMITS_H -# include -#else -# define UCHAR_MAX ((unsigned char)~0) -#endif -#include -#include "number.h" -#include "dc.h" -#include "dc-proto.h" - -#ifdef __GNUC__ -# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__-0 >= 7) -# define ATTRIB(x) __attribute__(x) -# endif -#endif -#ifndef ATTRIB -# define ATTRIB(x) -#endif - -/* Forward prototype */ -static void out_char (int); - -/* there is no POSIX standard for dc, so we'll take the GNU definitions */ -int std_only = FALSE; - -/* convert an opaque dc_num into a real bc_num */ -#define CastNum(x) ((bc_num)(x)) - -/* add two dc_nums, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_add DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale ATTRIB((unused)) DC_DECLSEP - dc_num *result DC_DECLEND -{ - bc_init_num((bc_num *)result); - bc_add(CastNum(a), CastNum(b), (bc_num *)result, 0); - return DC_SUCCESS; -} - -/* subtract two dc_nums, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_sub DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale ATTRIB((unused)) DC_DECLSEP - dc_num *result DC_DECLEND -{ - bc_init_num((bc_num *)result); - bc_sub(CastNum(a), CastNum(b), (bc_num *)result, 0); - return DC_SUCCESS; -} - -/* multiply two dc_nums, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_mul DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - bc_init_num((bc_num *)result); - bc_multiply(CastNum(a), CastNum(b), (bc_num *)result, kscale); - return DC_SUCCESS; -} - -/* divide two dc_nums, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_div DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - bc_init_num((bc_num *)result); - if (bc_divide(CastNum(a), CastNum(b), (bc_num *)result, kscale)){ - fprintf(stderr, "%s: divide by zero\n", progname); - return DC_DOMAIN_ERROR; - } - return DC_SUCCESS; -} - -/* divide two dc_nums, place quotient into *quotient and remainder - * into *remainder; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_divrem DC_DECLARG((a, b, kscale, quotient, remainder)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *quotient DC_DECLSEP - dc_num *remainder DC_DECLEND -{ - bc_init_num((bc_num *)quotient); - bc_init_num((bc_num *)remainder); - if (bc_divmod(CastNum(a), CastNum(b), - (bc_num *)quotient, (bc_num *)remainder, kscale)){ - fprintf(stderr, "%s: divide by zero\n", progname); - return DC_DOMAIN_ERROR; - } - return DC_SUCCESS; -} - -/* place the reminder of dividing a by b into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_rem DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - bc_init_num((bc_num *)result); - if (bc_modulo(CastNum(a), CastNum(b), (bc_num *)result, kscale)){ - fprintf(stderr, "%s: remainder by zero\n", progname); - return DC_DOMAIN_ERROR; - } - return DC_SUCCESS; -} - -int -dc_modexp DC_DECLARG((base, expo, mod, kscale, result)) - dc_num base DC_DECLSEP - dc_num expo DC_DECLSEP - dc_num mod DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - bc_init_num((bc_num *)result); - if (bc_raisemod(CastNum(base), CastNum(expo), CastNum(mod), - (bc_num *)result, kscale)){ - if (bc_is_zero(CastNum(mod))) - fprintf(stderr, "%s: remainder by zero\n", progname); - return DC_DOMAIN_ERROR; - } - return DC_SUCCESS; -} - -/* place the result of exponentiationg a by b into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_exp DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - bc_init_num((bc_num *)result); - bc_raise(CastNum(a), CastNum(b), (bc_num *)result, kscale); - return DC_SUCCESS; -} - -/* take the square root of the value, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_sqrt DC_DECLARG((value, kscale, result)) - dc_num value DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - bc_num tmp; - - tmp = bc_copy_num(CastNum(value)); - if (!bc_sqrt(&tmp, kscale)){ - fprintf(stderr, "%s: square root of negative number\n", progname); - bc_free_num(&tmp); - return DC_DOMAIN_ERROR; - } - *((bc_num *)result) = tmp; - return DC_SUCCESS; -} - -/* compare dc_nums a and b; - * return a negative value if a < b; - * return a positive value if a > b; - * return zero value if a == b - */ -int -dc_compare DC_DECLARG((a, b)) - dc_num a DC_DECLSEP - dc_num b DC_DECLEND -{ - return bc_compare(CastNum(a), CastNum(b)); -} - -/* attempt to convert a dc_num to its corresponding int value - * If discard_p is DC_TOSS then deallocate the value after use. - */ -int -dc_num2int DC_DECLARG((value, discard_p)) - dc_num value DC_DECLSEP - dc_discard discard_p DC_DECLEND -{ - long result; - - result = bc_num2long(CastNum(value)); - if (discard_p == DC_TOSS) - dc_free_num(&value); - return (int)result; -} - -/* convert a C integer value into a dc_num */ -/* For convenience of the caller, package the dc_num - * into a dc_data result. - */ -dc_data -dc_int2data DC_DECLARG((value)) - int value DC_DECLEND -{ - dc_data result; - - bc_init_num((bc_num *)&result.v.number); - bc_int2num((bc_num *)&result.v.number, value); - result.dc_type = DC_NUMBER; - return result; -} - -/* get a dc_num from some input stream; - * input is a function which knows how to read the desired input stream - * ibase is the input base (2<=ibase<=DC_IBASE_MAX) - * *readahead will be set to the readahead character consumed while - * looking for the end-of-number - */ -/* For convenience of the caller, package the dc_num - * into a dc_data result. - */ -dc_data -dc_getnum DC_DECLARG((input, ibase, readahead)) - int (*input) DC_PROTO((void)) DC_DECLSEP - int ibase DC_DECLSEP - int *readahead DC_DECLEND -{ - bc_num base; - bc_num result; - bc_num build; - bc_num tmp; - bc_num divisor; - dc_data full_result; - int negative = 0; - int digit; - int decimal; - int c; - - bc_init_num(&tmp); - bc_init_num(&build); - bc_init_num(&base); - result = bc_copy_num(_zero_); - bc_int2num(&base, ibase); - c = (*input)(); - while (isspace(c)) - c = (*input)(); - if (c == '_' || c == '-'){ - negative = c; - c = (*input)(); - }else if (c == '+'){ - c = (*input)(); - } - while (isspace(c)) - c = (*input)(); - for (;;){ - if (isdigit(c)) - digit = c - '0'; - else if ('A' <= c && c <= 'F') - digit = 10 + c - 'A'; - else - break; - c = (*input)(); - bc_int2num(&tmp, digit); - bc_multiply(result, base, &result, 0); - bc_add(result, tmp, &result, 0); - } - if (c == '.'){ - bc_free_num(&build); - bc_free_num(&tmp); - divisor = bc_copy_num(_one_); - build = bc_copy_num(_zero_); - decimal = 0; - for (;;){ - c = (*input)(); - if (isdigit(c)) - digit = c - '0'; - else if ('A' <= c && c <= 'F') - digit = 10 + c - 'A'; - else - break; - bc_int2num(&tmp, digit); - bc_multiply(build, base, &build, 0); - bc_add(build, tmp, &build, 0); - bc_multiply(divisor, base, &divisor, 0); - ++decimal; - } - bc_divide(build, divisor, &build, decimal); - bc_add(result, build, &result, 0); - } - /* Final work. */ - if (negative) - bc_sub(_zero_, result, &result, 0); - - bc_free_num(&tmp); - bc_free_num(&build); - bc_free_num(&base); - if (readahead) - *readahead = c; - full_result.v.number = (dc_num)result; - full_result.dc_type = DC_NUMBER; - return full_result; -} - - -/* return the "length" of the number */ -int -dc_numlen DC_DECLARG((value)) - dc_num value DC_DECLEND -{ - bc_num num = CastNum(value); - - /* is this right??? */ - return num->n_len + num->n_scale - (*num->n_value == '\0'); -} - -/* return the scale factor of the passed dc_num - * If discard_p is DC_TOSS then deallocate the value after use. - */ -int -dc_tell_scale DC_DECLARG((value, discard_p)) - dc_num value DC_DECLSEP - dc_discard discard_p DC_DECLEND -{ - int kscale; - - kscale = CastNum(value)->n_scale; - if (discard_p == DC_TOSS) - dc_free_num(&value); - return kscale; -} - - -/* initialize the math subsystem */ -void -dc_math_init DC_DECLVOID() -{ - bc_init_numbers(); -} - -/* print out a dc_num in output base obase to stdout; - * if newline_p is DC_WITHNL, terminate output with a '\n'; - * if discard_p is DC_TOSS then deallocate the value after use - */ -void -dc_out_num DC_DECLARG((value, obase, newline_p, discard_p)) - dc_num value DC_DECLSEP - int obase DC_DECLSEP - dc_newline newline_p DC_DECLSEP - dc_discard discard_p DC_DECLEND -{ - out_char('\0'); /* clear the column counter */ - bc_out_num(CastNum(value), obase, out_char, 0); - if (newline_p == DC_WITHNL) - putchar ('\n'); - if (discard_p == DC_TOSS) - dc_free_num(&value); -} - -/* dump out the absolute value of the integer part of a - * dc_num as a byte stream, without any line wrapping; - * if discard_p is DC_TOSS then deallocate the value after use - */ -void -dc_dump_num DC_DECLARG((dcvalue, discard_p)) - dc_num dcvalue DC_DECLSEP - dc_discard discard_p DC_DECLEND -{ - struct digit_stack { int digit; struct digit_stack *link;}; - struct digit_stack *top_of_stack = NULL; - struct digit_stack *cur; - struct digit_stack *next; - bc_num value; - bc_num obase; - bc_num digit; - - bc_init_num(&value); - bc_init_num(&obase); - bc_init_num(&digit); - - /* we only handle the integer portion: */ - bc_divide(CastNum(dcvalue), _one_, &value, 0); - /* we only handle the absolute value: */ - value->n_sign = PLUS; - /* we're done with the dcvalue parameter: */ - if (discard_p == DC_TOSS) - dc_free_num(&dcvalue); - - bc_int2num(&obase, 1+UCHAR_MAX); - do { - (void) bc_divmod(value, obase, &value, &digit, 0); - cur = dc_malloc(sizeof *cur); - cur->digit = (int)bc_num2long(digit); - cur->link = top_of_stack; - top_of_stack = cur; - } while (!bc_is_zero(value)); - - for (cur=top_of_stack; cur; cur=next) { - putchar(cur->digit); - next = cur->link; - free(cur); - } - - bc_free_num(&digit); - bc_free_num(&obase); - bc_free_num(&value); -} - -/* deallocate an instance of a dc_num */ -void -dc_free_num DC_DECLARG((value)) - dc_num *value DC_DECLEND -{ - bc_free_num((bc_num *)value); -} - -/* return a duplicate of the number in the passed value */ -/* The mismatched data types forces the caller to deal with - * bad dc_type'd dc_data values, and makes it more convenient - * for the caller to not have to do the grunge work of setting - * up a dc_type result. - */ -dc_data -dc_dup_num DC_DECLARG((value)) - dc_num value DC_DECLEND -{ - dc_data result; - - ++CastNum(value)->n_refs; - result.v.number = value; - result.dc_type = DC_NUMBER; - return result; -} - - - -/*---------------------------------------------------------------------------\ -| The rest of this file consists of stubs for bc routines called by numeric.c| -| so as to minimize the amount of bc code needed to build dc. | -| The bulk of the code was just lifted straight out of the bc source. | -\---------------------------------------------------------------------------*/ - -#ifdef HAVE_STDLIB_H -# include -#endif - -#ifdef HAVE_STDARG_H -# include -#else -# include -#endif - - -int out_col = 0; - -/* Output routines: Write a character CH to the standard output. - It keeps track of the number of characters output and may - break the output with a "\". */ - -static void -out_char (ch) - int ch; -{ - - if (ch == '\0') - { - out_col = 0; - } - else - { - out_col++; - if (out_col == 70) - { - putchar ('\\'); - putchar ('\n'); - out_col = 1; - } - putchar (ch); - } -} - -/* Malloc could not get enough memory. */ - -void -out_of_memory() -{ - dc_memfail(); -} - -/* Runtime error will print a message and stop the machine. */ - -#ifdef HAVE_STDARG_H -#ifdef __STDC__ -void -rt_error (char *mesg, ...) -#else -void -rt_error (mesg) - char *mesg; -#endif -#else -void -rt_error (mesg, va_alist) - char *mesg; -#endif -{ - va_list args; - - fprintf (stderr, "Runtime error: "); -#ifdef HAVE_STDARG_H - va_start (args, mesg); -#else - va_start (args); -#endif - vfprintf (stderr, mesg, args); - va_end (args); - fprintf (stderr, "\n"); -} - - -/* A runtime warning tells of some action taken by the processor that - may change the program execution but was not enough of a problem - to stop the execution. */ - -#ifdef HAVE_STDARG_H -#ifdef __STDC__ -void -rt_warn (char *mesg, ...) -#else -void -rt_warn (mesg) - char *mesg; -#endif -#else -void -rt_warn (mesg, va_alist) - char *mesg; -#endif -{ - va_list args; - - fprintf (stderr, "Runtime warning: "); -#ifdef HAVE_STDARG_H - va_start (args, mesg); -#else - va_start (args); -#endif - vfprintf (stderr, mesg, args); - va_end (args); - fprintf (stderr, "\n"); -} diff --git a/src/bin/bc/dc/stack.c b/src/bin/bc/dc/stack.c deleted file mode 100644 index 1d8a9bf731..0000000000 --- a/src/bin/bc/dc/stack.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - * implement stack functions for dc - * - * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -/* This module is the only one that knows what stacks (both the - * regular evaluation stack and the named register stacks) - * look like. - */ - -#include "config.h" - -#include -#ifdef HAVE_STDLIB_H -# include -#endif -#include "dc.h" -#include "dc-proto.h" -#include "dc-regdef.h" - -/* an oft-used error message: */ -#define Empty_Stack fprintf(stderr, "%s: stack empty\n", progname) - - -/* simple linked-list implementaion suffices: */ -struct dc_list { - dc_data value; - struct dc_array *array; /* opaque */ - struct dc_list *link; -}; -typedef struct dc_list dc_list; - -/* the anonymous evaluation stack */ -static dc_list *dc_stack=NULL; - -/* the named register stacks */ -static dc_list *dc_register[DC_REGCOUNT]; - - -/* allocate a new dc_list item */ -static dc_list * -dc_alloc DC_DECLVOID() -{ - dc_list *result; - - result = dc_malloc(sizeof *result); - result->value.dc_type = DC_UNINITIALIZED; - result->array = NULL; - result->link = NULL; - return result; -} - - -/* check that there are two numbers on top of the stack, - * then call op with the popped numbers. Construct a dc_data - * value from the dc_num returned by op and push it - * on the stack. - * If the op call doesn't return DC_SUCCESS, then leave the stack - * unmodified. - */ -void -dc_binop DC_DECLARG((op, kscale)) - int (*op)DC_PROTO((dc_num, dc_num, int, dc_num *)) DC_DECLSEP - int kscale DC_DECLEND -{ - dc_data a; - dc_data b; - dc_data r; - - if (!dc_stack || !dc_stack->link){ - Empty_Stack; - return; - } - if (dc_stack->value.dc_type!=DC_NUMBER - || dc_stack->link->value.dc_type!=DC_NUMBER){ - fprintf(stderr, "%s: non-numeric value\n", progname); - return; - } - (void)dc_pop(&b); - (void)dc_pop(&a); - if ((*op)(a.v.number, b.v.number, kscale, &r.v.number) == DC_SUCCESS){ - r.dc_type = DC_NUMBER; - dc_push(r); - dc_free_num(&a.v.number); - dc_free_num(&b.v.number); - }else{ - /* op failed; restore the stack */ - dc_push(a); - dc_push(b); - } -} - -/* check that there are two numbers on top of the stack, - * then call op with the popped numbers. Construct two dc_data - * values from the dc_num's returned by op and push them - * on the stack. - * If the op call doesn't return DC_SUCCESS, then leave the stack - * unmodified. - */ -void -dc_binop2 DC_DECLARG((op, kscale)) - int (*op)DC_PROTO((dc_num, dc_num, int, dc_num *, dc_num *)) DC_DECLSEP - int kscale DC_DECLEND -{ - dc_data a; - dc_data b; - dc_data r1; - dc_data r2; - - if (!dc_stack || !dc_stack->link){ - Empty_Stack; - return; - } - if (dc_stack->value.dc_type!=DC_NUMBER - || dc_stack->link->value.dc_type!=DC_NUMBER){ - fprintf(stderr, "%s: non-numeric value\n", progname); - return; - } - (void)dc_pop(&b); - (void)dc_pop(&a); - if ((*op)(a.v.number, b.v.number, kscale, - &r1.v.number, &r2.v.number) == DC_SUCCESS){ - r1.dc_type = DC_NUMBER; - dc_push(r1); - r2.dc_type = DC_NUMBER; - dc_push(r2); - dc_free_num(&a.v.number); - dc_free_num(&b.v.number); - }else{ - /* op failed; restore the stack */ - dc_push(a); - dc_push(b); - } -} - -/* check that there are two numbers on top of the stack, - * then call dc_compare with the popped numbers. - * Return negative, zero, or positive based on the ordering - * of the two numbers. - */ -int -dc_cmpop DC_DECLVOID() -{ - int result; - dc_data a; - dc_data b; - - if (!dc_stack || !dc_stack->link){ - Empty_Stack; - return 0; - } - if (dc_stack->value.dc_type!=DC_NUMBER - || dc_stack->link->value.dc_type!=DC_NUMBER){ - fprintf(stderr, "%s: non-numeric value\n", progname); - return 0; - } - (void)dc_pop(&b); - (void)dc_pop(&a); - result = dc_compare(b.v.number, a.v.number); - dc_free_num(&a.v.number); - dc_free_num(&b.v.number); - return result; -} - -/* check that there are three numbers on top of the stack, - * then call op with the popped numbers. Construct a dc_data - * value from the dc_num returned by op and push it - * on the stack. - * If the op call doesn't return DC_SUCCESS, then leave the stack - * unmodified. - */ -void -dc_triop DC_DECLARG((op, kscale)) - int (*op)DC_PROTO((dc_num, dc_num, dc_num, int, dc_num *)) DC_DECLSEP - int kscale DC_DECLEND -{ - dc_data a; - dc_data b; - dc_data c; - dc_data r; - - if (!dc_stack || !dc_stack->link || !dc_stack->link->link){ - Empty_Stack; - return; - } - if (dc_stack->value.dc_type!=DC_NUMBER - || dc_stack->link->value.dc_type!=DC_NUMBER - || dc_stack->link->link->value.dc_type!=DC_NUMBER){ - fprintf(stderr, "%s: non-numeric value\n", progname); - return; - } - (void)dc_pop(&c); - (void)dc_pop(&b); - (void)dc_pop(&a); - if ((*op)(a.v.number, b.v.number, c.v.number, - kscale, &r.v.number) == DC_SUCCESS){ - r.dc_type = DC_NUMBER; - dc_push(r); - dc_free_num(&a.v.number); - dc_free_num(&b.v.number); - dc_free_num(&c.v.number); - }else{ - /* op failed; restore the stack */ - dc_push(a); - dc_push(b); - dc_push(c); - } -} - - -/* initialize the register stacks to their initial values */ -void -dc_register_init DC_DECLVOID() -{ - int i; - - for (i=0; ilink; - if (n->value.dc_type == DC_NUMBER) - dc_free_num(&n->value.v.number); - else if (n->value.dc_type == DC_STRING) - dc_free_str(&n->value.v.string); - else - dc_garbage("in stack", -1); - dc_array_free(n->array); - free(n); - } - dc_stack = NULL; -} - -/* push a value onto the evaluation stack */ -void -dc_push DC_DECLARG((value)) - dc_data value DC_DECLEND -{ - dc_list *n = dc_alloc(); - - if (value.dc_type!=DC_NUMBER && value.dc_type!=DC_STRING) - dc_garbage("in data being pushed", -1); - n->value = value; - n->link = dc_stack; - dc_stack = n; -} - -/* push a value onto the named register stack */ -void -dc_register_push DC_DECLARG((stackid, value)) - int stackid DC_DECLSEP - dc_data value DC_DECLEND -{ - dc_list *n = dc_alloc(); - - stackid = regmap(stackid); - n->value = value; - n->link = dc_register[stackid]; - dc_register[stackid] = n; -} - -/* set *result to the value on the top of the evaluation stack */ -/* The caller is responsible for duplicating the value if it - * is to be maintained as anything more than a transient identity. - * - * DC_FAIL is returned if the stack is empty (and *result unchanged), - * DC_SUCCESS is returned otherwise - */ -int -dc_top_of_stack DC_DECLARG((result)) - dc_data *result DC_DECLEND -{ - if (!dc_stack){ - Empty_Stack; - return DC_FAIL; - } - if (dc_stack->value.dc_type!=DC_NUMBER - && dc_stack->value.dc_type!=DC_STRING) - dc_garbage("at top of stack", -1); - *result = dc_stack->value; - return DC_SUCCESS; -} - -/* set *result to a dup of the value on the top of the named register stack */ -/* - * DC_FAIL is returned if the named stack is empty (and *result unchanged), - * DC_SUCCESS is returned otherwise - */ -int -dc_register_get DC_DECLARG((regid, result)) - int regid DC_DECLSEP - dc_data *result DC_DECLEND -{ - dc_list *r; - - regid = regmap(regid); - r = dc_register[regid]; - if ( ! r ){ - fprintf(stderr, "%s: register ", progname); - dc_show_id(stderr, regid, " is empty\n"); - return DC_FAIL; - } - *result = dc_dup(r->value); - return DC_SUCCESS; -} - -/* set the top of the named register stack to the indicated value */ -/* If the named stack is empty, craft a stack entry to enter the - * value into. - */ -void -dc_register_set DC_DECLARG((regid, value)) - int regid DC_DECLSEP - dc_data value DC_DECLEND -{ - dc_list *r; - - regid = regmap(regid); - r = dc_register[regid]; - if ( ! r ) - dc_register[regid] = dc_alloc(); - else if (r->value.dc_type == DC_NUMBER) - dc_free_num(&r->value.v.number); - else if (r->value.dc_type == DC_STRING) - dc_free_str(&r->value.v.string); - else if (r->value.dc_type == DC_UNINITIALIZED) - ; - else - dc_garbage("", regid); - dc_register[regid]->value = value; -} - -/* pop from the evaluation stack - * - * DC_FAIL is returned if the stack is empty (and *result unchanged), - * DC_SUCCESS is returned otherwise - */ -int -dc_pop DC_DECLARG((result)) - dc_data *result DC_DECLEND -{ - dc_list *r; - - r = dc_stack; - if (!r){ - Empty_Stack; - return DC_FAIL; - } - if (r->value.dc_type!=DC_NUMBER && r->value.dc_type!=DC_STRING) - dc_garbage("at top of stack", -1); - *result = r->value; - dc_stack = r->link; - dc_array_free(r->array); - free(r); - return DC_SUCCESS; -} - -/* pop from the named register stack - * - * DC_FAIL is returned if the named stack is empty (and *result unchanged), - * DC_SUCCESS is returned otherwise - */ -int -dc_register_pop DC_DECLARG((stackid, result)) - int stackid DC_DECLSEP - dc_data *result DC_DECLEND -{ - dc_list *r; - - stackid = regmap(stackid); - r = dc_register[stackid]; - if (!r){ - fprintf(stderr, "%s: stack register ", progname); - dc_show_id(stderr, stackid, " is empty\n"); - return DC_FAIL; - } - if (r->value.dc_type!=DC_NUMBER && r->value.dc_type!=DC_STRING) - dc_garbage(" stack", stackid); - *result = r->value; - dc_register[stackid] = r->link; - dc_array_free(r->array); - free(r); - return DC_SUCCESS; -} - - -/* tell how many entries are currently on the evaluation stack */ -int -dc_tell_stackdepth DC_DECLVOID() -{ - dc_list *n; - int depth=0; - - for (n=dc_stack; n; n=n->link) - ++depth; - return depth; -} - - -/* return the length of the indicated data value; - * if discard_p is DC_TOSS, the deallocate the value when done - * - * The definition of a datum's length is deligated to the - * appropriate module. - */ -int -dc_tell_length DC_DECLARG((value, discard_p)) - dc_data value DC_DECLSEP - dc_discard discard_p DC_DECLEND -{ - int length; - - if (value.dc_type == DC_NUMBER){ - length = dc_numlen(value.v.number); - if (discard_p == DC_TOSS) - dc_free_num(&value.v.number); - } else if (value.dc_type == DC_STRING) { - length = dc_strlen(value.v.string); - if (discard_p == DC_TOSS) - dc_free_str(&value.v.string); - } else { - dc_garbage("in tell_length", -1); - /*NOTREACHED*/ - length = 0; /*just to suppress spurious compiler warnings*/ - } - return length; -} - - - -/* print out all of the values on the evaluation stack */ -void -dc_printall DC_DECLARG((obase)) - int obase DC_DECLEND -{ - dc_list *n; - - for (n=dc_stack; n; n=n->link) - dc_print(n->value, obase, DC_WITHNL, DC_KEEP); -} - - - - -/* get the current array head for the named array */ -struct dc_array * -dc_get_stacked_array DC_DECLARG((array_id)) - int array_id DC_DECLEND -{ - dc_list *r = dc_register[regmap(array_id)]; - return r ? r->array : NULL; -} - -/* set the current array head for the named array */ -void -dc_set_stacked_array DC_DECLARG((array_id, new_head)) - int array_id DC_DECLSEP - struct dc_array *new_head DC_DECLEND -{ - dc_list *r; - - array_id = regmap(array_id); - r = dc_register[array_id]; - if ( ! r ) - r = dc_register[array_id] = dc_alloc(); - r->array = new_head; -} diff --git a/src/bin/bc/dc/string.c b/src/bin/bc/dc/string.c deleted file mode 100644 index a7f79a47ef..0000000000 --- a/src/bin/bc/dc/string.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * implement string functions for dc - * - * Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: - * - * The Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111 USA - */ - -/* This should be the only module that knows the internals of type dc_string */ - -#include "config.h" - -#include -#ifdef HAVE_STDDEF_H -# include /* ptrdiff_t */ -#else -# define ptrdiff_t size_t -#endif -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_STRING_H -# include /* memcpy */ -#else -# ifdef HAVE_MEMORY_H -# include /* memcpy, maybe */ -# else -# ifdef HAVE_STRINGS_H -# include /* memcpy, maybe */ -# endif -# endif -#endif -#include "dc.h" -#include "dc-proto.h" - -/* here is the completion of the dc_string type: */ -struct dc_string { - char *s_ptr; /* pointer to base of string */ - size_t s_len; /* length of counted string */ - int s_refs; /* reference count to cut down on memory use by duplicates */ -}; - - -/* return a duplicate of the string in the passed value */ -/* The mismatched data types forces the caller to deal with - * bad dc_type'd dc_data values, and makes it more convenient - * for the caller to not have to do the grunge work of setting - * up a dc_type result. - */ -dc_data -dc_dup_str DC_DECLARG((value)) - dc_str value DC_DECLEND -{ - dc_data result; - - ++value->s_refs; - result.v.string = value; - result.dc_type = DC_STRING; - return result; -} - -/* free an instance of a dc_str value */ -void -dc_free_str DC_DECLARG((value)) - dc_str *value DC_DECLEND -{ - struct dc_string *string = *value; - - if (--string->s_refs < 1){ - free(string->s_ptr); - free(string); - } -} - -/* Output a dc_str value. - * Add a trailing newline if "newline" is set. - * Free the value after use if discard_flag is set. - */ -void -dc_out_str DC_DECLARG((value, newline, discard_flag)) - dc_str value DC_DECLSEP - dc_newline newline DC_DECLSEP - dc_discard discard_flag DC_DECLEND -{ - fwrite(value->s_ptr, value->s_len, sizeof *value->s_ptr, stdout); - if (newline == DC_WITHNL) - putchar('\n'); - if (discard_flag == DC_TOSS) - dc_free_str(&value); -} - -/* make a copy of a string (base s, length len) - * into a dc_str value; return a dc_data result - * with this value - */ -dc_data -dc_makestring DC_DECLARG((s, len)) - const char *s DC_DECLSEP - size_t len DC_DECLEND -{ - dc_data result; - struct dc_string *string; - - string = dc_malloc(sizeof *string); - string->s_ptr = dc_malloc(len+1); - memcpy(string->s_ptr, s, len); - string->s_ptr[len] = '\0'; /* nul terminated for those who need it */ - string->s_len = len; - string->s_refs = 1; - result.v.string = string; - result.dc_type = DC_STRING; - return result; -} - -/* read a dc_str value from FILE *fp; - * if ldelim == rdelim, then read until a ldelim char or EOF is reached; - * if ldelim != rdelim, then read until a matching rdelim for the - * (already eaten) first ldelim is read. - * Return a dc_data result with the dc_str value as its contents. - */ -dc_data -dc_readstring DC_DECLARG((fp, ldelim, rdelim)) - FILE *fp DC_DECLSEP - int ldelim DC_DECLSEP - int rdelim DC_DECLEND -{ - static char *line_buf = NULL; /* a buffer to build the string in */ - static size_t buflen = 0; /* the current size of line_buf */ - int depth=1; - int c; - char *p; - const char *end; - - if (!line_buf){ - /* initial buflen should be large enough to handle most cases */ - buflen = 2016; - line_buf = dc_malloc(buflen); - } - p = line_buf; - end = line_buf + buflen; - for (;;){ - c = getc(fp); - if (c == EOF) - break; - else if (c == rdelim && --depth < 1) - break; - else if (c == ldelim) - ++depth; - if (p >= end){ - ptrdiff_t offset = p - line_buf; - /* buflen increment should be big enough - * to avoid execessive reallocs: - */ - buflen += 2048; - line_buf = realloc(line_buf, buflen); - if (!line_buf) - dc_memfail(); - p = line_buf + offset; - end = line_buf + buflen; - } - *p++ = c; - } - return dc_makestring(line_buf, (size_t)(p-line_buf)); -} - -/* return the base pointer of the dc_str value; - * This function is needed because no one else knows what dc_str - * looks like. - */ -const char * -dc_str2charp DC_DECLARG((value)) - dc_str value DC_DECLEND -{ - return value->s_ptr; -} - -/* return the length of the dc_str value; - * This function is needed because no one else knows what dc_str - * looks like, and strlen(dc_str2charp(value)) won't work - * if there's an embedded '\0'. - */ -size_t -dc_strlen DC_DECLARG((value)) - dc_str value DC_DECLEND -{ - return value->s_len; -} - - -/* initialize the strings subsystem */ -void -dc_string_init DC_DECLVOID() -{ - /* nothing to do for this implementation */ -} diff --git a/src/bin/bc/h/getopt.h b/src/bin/bc/h/getopt.h deleted file mode 100644 index f3696d955d..0000000000 --- a/src/bin/bc/h/getopt.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc. - -This file is part of the GNU C Library. Its master source is NOT part of -the C library, however. The master source lives in /gd/gnu/lib. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -#if defined (__STDC__) && __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -#if defined (__STDC__) && __STDC__ -#ifdef __GNU_LIBRARY__ -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int argc, char *const *argv, const char *shortopts); -#else /* not __GNU_LIBRARY__ */ -extern int getopt (); -#endif /* __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -#endif /* __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/src/bin/bc/h/number.h b/src/bin/bc/h/number.h deleted file mode 100644 index 8d781208b7..0000000000 --- a/src/bin/bc/h/number.h +++ /dev/null @@ -1,153 +0,0 @@ -/* number.h: Arbitrary precision numbers header file. */ -/* - Copyright (C) 1991, 1992, 1993, 1994, 1997, 2000 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to: - - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111-1307 USA. - - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#ifndef _NUMBER_H_ -#define _NUMBER_H_ - -typedef enum {PLUS, MINUS} sign; - -typedef struct bc_struct *bc_num; - -typedef struct bc_struct - { - sign n_sign; - int n_len; /* The number of digits before the decimal point. */ - int n_scale; /* The number of digits after the decimal point. */ - int n_refs; /* The number of pointers to this number. */ - bc_num n_next; /* Linked list for available list. */ - char *n_ptr; /* The pointer to the actual storage. - If NULL, n_value points to the inside of - another number (bc_multiply...) and should - not be "freed." */ - char *n_value; /* The number. Not zero char terminated. - May not point to the same place as n_ptr as - in the case of leading zeros generated. */ - } bc_struct; - - -/* The base used in storing the numbers in n_value above. - Currently this MUST be 10. */ - -#define BASE 10 - -/* Some useful macros and constants. */ - -#define CH_VAL(c) (c - '0') -#define BCD_CHAR(d) (d + '0') - -#ifdef MIN -#undef MIN -#undef MAX -#endif -#define MAX(a,b) ((a)>(b)?(a):(b)) -#define MIN(a,b) ((a)>(b)?(b):(a)) -#define ODD(a) ((a)&1) - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#ifndef LONG_MAX -#define LONG_MAX 0x7ffffff -#endif - - -/* Global numbers. */ -extern bc_num _zero_; -extern bc_num _one_; -extern bc_num _two_; - - -/* Function Prototypes */ - -/* Define the _PROTOTYPE macro if it is needed. */ - -#ifndef _PROTOTYPE -#ifdef __STDC__ -#define _PROTOTYPE(func, args) func args -#else -#define _PROTOTYPE(func, args) func() -#endif -#endif - -_PROTOTYPE(void bc_init_numbers, (void)); - -_PROTOTYPE(bc_num bc_new_num, (int length, int scale)); - -_PROTOTYPE(void bc_free_num, (bc_num *num)); - -_PROTOTYPE(bc_num bc_copy_num, (bc_num num)); - -_PROTOTYPE(void bc_init_num, (bc_num *num)); - -_PROTOTYPE(void bc_str2num, (bc_num *num, char *str, int scale)); - -_PROTOTYPE(char *bc_num2str, (bc_num num)); - -_PROTOTYPE(void bc_int2num, (bc_num *num, int val)); - -_PROTOTYPE(long bc_num2long, (bc_num num)); - -_PROTOTYPE(int bc_compare, (bc_num n1, bc_num n2)); - -_PROTOTYPE(char bc_is_zero, (bc_num num)); - -_PROTOTYPE(char bc_is_near_zero, (bc_num num, int scale)); - -_PROTOTYPE(char bc_is_neg, (bc_num num)); - -_PROTOTYPE(void bc_add, (bc_num n1, bc_num n2, bc_num *result, int scale_min)); - -_PROTOTYPE(void bc_sub, (bc_num n1, bc_num n2, bc_num *result, int scale_min)); - -_PROTOTYPE(void bc_multiply, (bc_num n1, bc_num n2, bc_num *prod, int scale)); - -_PROTOTYPE(int bc_divide, (bc_num n1, bc_num n2, bc_num *quot, int scale)); - -_PROTOTYPE(int bc_modulo, (bc_num num1, bc_num num2, bc_num *result, - int scale)); - -_PROTOTYPE(int bc_divmod, (bc_num num1, bc_num num2, bc_num *quot, - bc_num *rem, int scale)); - -_PROTOTYPE(int bc_raisemod, (bc_num base, bc_num expo, bc_num mod, - bc_num *result, int scale)); - -_PROTOTYPE(void bc_raise, (bc_num num1, bc_num num2, bc_num *result, - int scale)); - -_PROTOTYPE(int bc_sqrt, (bc_num *num, int scale)); - -_PROTOTYPE(void bc_out_num, (bc_num num, int o_base, void (* out_char)(int), - int leading_zero)); - -#endif diff --git a/src/bin/bc/lib/Jamfile b/src/bin/bc/lib/Jamfile deleted file mode 100644 index 1e37fc47b3..0000000000 --- a/src/bin/bc/lib/Jamfile +++ /dev/null @@ -1,10 +0,0 @@ -SubDir HAIKU_TOP src bin bc lib ; - -SubDirCcFlags -DHAVE_CONFIG_H ; - -SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; -SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) h ] ; - -StaticLibrary libbc.a : - getopt.c getopt1.c vfprintf.c number.c -; diff --git a/src/bin/bc/lib/getopt.c b/src/bin/bc/lib/getopt.c deleted file mode 100644 index 23ce0648b7..0000000000 --- a/src/bin/bc/lib/getopt.c +++ /dev/null @@ -1,752 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu - before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 - Free Software Foundation, Inc. - -This file is part of the GNU C Library. Its master source is NOT part of -the C library, however. The master source lives in /gd/gnu/lib. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -/* This tells Alpha OSF/1 not to define a getopt prototype in . - Ditto for AIX 3.2 and . */ -#ifndef _NO_PROTO -#define _NO_PROTO -#endif - -#ifdef HAVE_CONFIG_H -#include -#endif - -#if !defined (__STDC__) || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -#include -#endif /* GNU C library. */ - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg = NULL; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* XXX 1003.2 says this must be 1 before any call. */ -int optind = 0; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return EOF with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Value of POSIXLY_CORRECT environment variable. */ -static char *posixly_correct; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -#include -#define my_index strchr -#else - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -char *getenv (); - -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -/* If using GCC, we can safely declare strlen this way. - If not using GCC, it is ok not to declare it. */ -#ifdef __GNUC__ -/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. - That was relevant to code that was here before. */ -#if !defined (__STDC__) || !__STDC__ -/* gcc with -traditional declares the built-in strlen to return int, - and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); -#endif /* not __STDC__ */ -#endif /* __GNUC__ */ - -#endif /* not __GNU_LIBRARY__ */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -static void -exchange (argv) - char **argv; -{ - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Initialize the internal data when the first call is made. */ - -static const char * -_getopt_initialize (optstring) - const char *optstring; -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - first_nonopt = last_nonopt = optind = 1; - - nextchar = NULL; - - posixly_correct = getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns `EOF'. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; -{ - optarg = NULL; - - if (optind == 0) - optstring = _getopt_initialize (optstring); - - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc - && (argv[optind][0] != '-' || argv[optind][1] == '\0')) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return EOF; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) - { - if (ordering == REQUIRE_ORDER) - return EOF; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if (nameend - nextchar == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); - else - fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); - } - optopt = c; - return '?'; - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: option requires an argument -- %c\n", - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/src/bin/bc/lib/getopt1.c b/src/bin/bc/lib/getopt1.c deleted file mode 100644 index de8e2ad567..0000000000 --- a/src/bin/bc/lib/getopt1.c +++ /dev/null @@ -1,184 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994 - Free Software Foundation, Inc. - -This file is part of the GNU C Library. Its master source is NOT part of -the C library, however. The master source lives in /gd/gnu/lib. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "getopt.h" - -#if !defined (__STDC__) || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#else -char *getenv (); -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); -} - - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -#include - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == EOF) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/src/bin/bc/lib/number.c b/src/bin/bc/lib/number.c deleted file mode 100644 index 1f913d5350..0000000000 --- a/src/bin/bc/lib/number.c +++ /dev/null @@ -1,1793 +0,0 @@ -/* number.c: Implements arbitrary precision numbers. */ -/* - Copyright (C) 1991, 1992, 1993, 1994, 1997, 2000 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License , or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to: - - The Free Software Foundation, Inc. - 59 Temple Place, Suite 330 - Boston, MA 02111-1307 USA. - - - You may contact the author by: - e-mail: philnelson@acm.org - us-mail: Philip A. Nelson - Computer Science Department, 9062 - Western Washington University - Bellingham, WA 98226-9062 - -*************************************************************************/ - -#include -#include -#include -#include -#include -#include /* Prototypes needed for external utility routines. */ - -#define bc_rt_warn rt_warn -#define bc_rt_error rt_error -#define bc_out_of_memory out_of_memory - -_PROTOTYPE(void rt_warn, (char *mesg ,...)); -_PROTOTYPE(void rt_error, (char *mesg ,...)); -_PROTOTYPE(void out_of_memory, (void)); - -/* Storage used for special numbers. */ -bc_num _zero_; -bc_num _one_; -bc_num _two_; - -static bc_num _bc_Free_list = NULL; - -/* new_num allocates a number and sets fields to known values. */ - -bc_num -bc_new_num (length, scale) - int length, scale; -{ - bc_num temp; - - if (_bc_Free_list != NULL) { - temp = _bc_Free_list; - _bc_Free_list = temp->n_next; - } else { - temp = (bc_num) malloc (sizeof(bc_struct)); - if (temp == NULL) bc_out_of_memory (); - } - temp->n_sign = PLUS; - temp->n_len = length; - temp->n_scale = scale; - temp->n_refs = 1; - temp->n_ptr = (char *) malloc (length+scale); - if (temp->n_ptr == NULL) bc_out_of_memory(); - temp->n_value = temp->n_ptr; - memset (temp->n_ptr, 0, length+scale); - return temp; -} - -/* "Frees" a bc_num NUM. Actually decreases reference count and only - frees the storage if reference count is zero. */ - -void -bc_free_num (num) - bc_num *num; -{ - if (*num == NULL) return; - (*num)->n_refs--; - if ((*num)->n_refs == 0) { - if ((*num)->n_ptr) - free ((*num)->n_ptr); - (*num)->n_next = _bc_Free_list; - _bc_Free_list = *num; - } - *num = NULL; -} - - -/* Intitialize the number package! */ - -void -bc_init_numbers () -{ - _zero_ = bc_new_num (1,0); - _one_ = bc_new_num (1,0); - _one_->n_value[0] = 1; - _two_ = bc_new_num (1,0); - _two_->n_value[0] = 2; -} - - -/* Make a copy of a number! Just increments the reference count! */ - -bc_num -bc_copy_num (num) - bc_num num; -{ - num->n_refs++; - return num; -} - - -/* Initialize a number NUM by making it a copy of zero. */ - -void -bc_init_num (num) - bc_num *num; -{ - *num = bc_copy_num (_zero_); -} - -/* For many things, we may have leading zeros in a number NUM. - _bc_rm_leading_zeros just moves the data "value" pointer to the - correct place and adjusts the length. */ - -static void -_bc_rm_leading_zeros (num) - bc_num num; -{ - /* We can move n_value to point to the first non zero digit! */ - while (*num->n_value == 0 && num->n_len > 1) { - num->n_value++; - num->n_len--; - } -} - - -/* Compare two bc numbers. Return value is 0 if equal, -1 if N1 is less - than N2 and +1 if N1 is greater than N2. If USE_SIGN is false, just - compare the magnitudes. */ - -static int -_bc_do_compare (n1, n2, use_sign, ignore_last) - bc_num n1, n2; - int use_sign; - int ignore_last; -{ - char *n1ptr, *n2ptr; - int count; - - /* First, compare signs. */ - if (use_sign && n1->n_sign != n2->n_sign) - { - if (n1->n_sign == PLUS) - return (1); /* Positive N1 > Negative N2 */ - else - return (-1); /* Negative N1 < Positive N1 */ - } - - /* Now compare the magnitude. */ - if (n1->n_len != n2->n_len) - { - if (n1->n_len > n2->n_len) - { - /* Magnitude of n1 > n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (1); - else - return (-1); - } - else - { - /* Magnitude of n1 < n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (-1); - else - return (1); - } - } - - /* If we get here, they have the same number of integer digits. - check the integer part and the equal length part of the fraction. */ - count = n1->n_len + MIN (n1->n_scale, n2->n_scale); - n1ptr = n1->n_value; - n2ptr = n2->n_value; - - while ((count > 0) && (*n1ptr == *n2ptr)) - { - n1ptr++; - n2ptr++; - count--; - } - if (ignore_last && count == 1 && n1->n_scale == n2->n_scale) - return (0); - if (count != 0) - { - if (*n1ptr > *n2ptr) - { - /* Magnitude of n1 > n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (1); - else - return (-1); - } - else - { - /* Magnitude of n1 < n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (-1); - else - return (1); - } - } - - /* They are equal up to the last part of the equal part of the fraction. */ - if (n1->n_scale != n2->n_scale) - { - if (n1->n_scale > n2->n_scale) - { - for (count = n1->n_scale-n2->n_scale; count>0; count--) - if (*n1ptr++ != 0) - { - /* Magnitude of n1 > n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (1); - else - return (-1); - } - } - else - { - for (count = n2->n_scale-n1->n_scale; count>0; count--) - if (*n2ptr++ != 0) - { - /* Magnitude of n1 < n2. */ - if (!use_sign || n1->n_sign == PLUS) - return (-1); - else - return (1); - } - } - } - - /* They must be equal! */ - return (0); -} - - -/* This is the "user callable" routine to compare numbers N1 and N2. */ - -int -bc_compare (n1, n2) - bc_num n1, n2; -{ - return _bc_do_compare (n1, n2, TRUE, FALSE); -} - -/* In some places we need to check if the number is negative. */ - -char -bc_is_neg (num) - bc_num num; -{ - return num->n_sign == MINUS; -} - -/* In some places we need to check if the number NUM is zero. */ - -char -bc_is_zero (num) - bc_num num; -{ - int count; - char *nptr; - - /* Quick check. */ - if (num == _zero_) return TRUE; - - /* Initialize */ - count = num->n_len + num->n_scale; - nptr = num->n_value; - - /* The check */ - while ((count > 0) && (*nptr++ == 0)) count--; - - if (count != 0) - return FALSE; - else - return TRUE; -} - -/* In some places we need to check if the number NUM is almost zero. - Specifically, all but the last digit is 0 and the last digit is 1. - Last digit is defined by scale. */ - -char -bc_is_near_zero (num, scale) - bc_num num; - int scale; -{ - int count; - char *nptr; - - /* Error checking */ - if (scale > num->n_scale) - scale = num->n_scale; - - /* Initialize */ - count = num->n_len + scale; - nptr = num->n_value; - - /* The check */ - while ((count > 0) && (*nptr++ == 0)) count--; - - if (count != 0 && (count != 1 || *--nptr != 1)) - return FALSE; - else - return TRUE; -} - - -/* Perform addition: N1 is added to N2 and the value is - returned. The signs of N1 and N2 are ignored. - SCALE_MIN is to set the minimum scale of the result. */ - -static bc_num -_bc_do_add (n1, n2, scale_min) - bc_num n1, n2; - int scale_min; -{ - bc_num sum; - int sum_scale, sum_digits; - char *n1ptr, *n2ptr, *sumptr; - int carry, n1bytes, n2bytes; - int count; - - /* Prepare sum. */ - sum_scale = MAX (n1->n_scale, n2->n_scale); - sum_digits = MAX (n1->n_len, n2->n_len) + 1; - sum = bc_new_num (sum_digits, MAX(sum_scale, scale_min)); - - /* Zero extra digits made by scale_min. */ - if (scale_min > sum_scale) - { - sumptr = (char *) (sum->n_value + sum_scale + sum_digits); - for (count = scale_min - sum_scale; count > 0; count--) - *sumptr++ = 0; - } - - /* Start with the fraction part. Initialize the pointers. */ - n1bytes = n1->n_scale; - n2bytes = n2->n_scale; - n1ptr = (char *) (n1->n_value + n1->n_len + n1bytes - 1); - n2ptr = (char *) (n2->n_value + n2->n_len + n2bytes - 1); - sumptr = (char *) (sum->n_value + sum_scale + sum_digits - 1); - - /* Add the fraction part. First copy the longer fraction.*/ - if (n1bytes != n2bytes) - { - if (n1bytes > n2bytes) - while (n1bytes>n2bytes) - { *sumptr-- = *n1ptr--; n1bytes--;} - else - while (n2bytes>n1bytes) - { *sumptr-- = *n2ptr--; n2bytes--;} - } - - /* Now add the remaining fraction part and equal size integer parts. */ - n1bytes += n1->n_len; - n2bytes += n2->n_len; - carry = 0; - while ((n1bytes > 0) && (n2bytes > 0)) - { - *sumptr = *n1ptr-- + *n2ptr-- + carry; - if (*sumptr > (BASE-1)) - { - carry = 1; - *sumptr -= BASE; - } - else - carry = 0; - sumptr--; - n1bytes--; - n2bytes--; - } - - /* Now add carry the longer integer part. */ - if (n1bytes == 0) - { n1bytes = n2bytes; n1ptr = n2ptr; } - while (n1bytes-- > 0) - { - *sumptr = *n1ptr-- + carry; - if (*sumptr > (BASE-1)) - { - carry = 1; - *sumptr -= BASE; - } - else - carry = 0; - sumptr--; - } - - /* Set final carry. */ - if (carry == 1) - *sumptr += 1; - - /* Adjust sum and return. */ - _bc_rm_leading_zeros (sum); - return sum; -} - - -/* Perform subtraction: N2 is subtracted from N1 and the value is - returned. The signs of N1 and N2 are ignored. Also, N1 is - assumed to be larger than N2. SCALE_MIN is the minimum scale - of the result. */ - -static bc_num -_bc_do_sub (n1, n2, scale_min) - bc_num n1, n2; - int scale_min; -{ - bc_num diff; - int diff_scale, diff_len; - int min_scale, min_len; - char *n1ptr, *n2ptr, *diffptr; - int borrow, count, val; - - /* Allocate temporary storage. */ - diff_len = MAX (n1->n_len, n2->n_len); - diff_scale = MAX (n1->n_scale, n2->n_scale); - min_len = MIN (n1->n_len, n2->n_len); - min_scale = MIN (n1->n_scale, n2->n_scale); - diff = bc_new_num (diff_len, MAX(diff_scale, scale_min)); - - /* Zero extra digits made by scale_min. */ - if (scale_min > diff_scale) - { - diffptr = (char *) (diff->n_value + diff_len + diff_scale); - for (count = scale_min - diff_scale; count > 0; count--) - *diffptr++ = 0; - } - - /* Initialize the subtract. */ - n1ptr = (char *) (n1->n_value + n1->n_len + n1->n_scale -1); - n2ptr = (char *) (n2->n_value + n2->n_len + n2->n_scale -1); - diffptr = (char *) (diff->n_value + diff_len + diff_scale -1); - - /* Subtract the numbers. */ - borrow = 0; - - /* Take care of the longer scaled number. */ - if (n1->n_scale != min_scale) - { - /* n1 has the longer scale */ - for (count = n1->n_scale - min_scale; count > 0; count--) - *diffptr-- = *n1ptr--; - } - else - { - /* n2 has the longer scale */ - for (count = n2->n_scale - min_scale; count > 0; count--) - { - val = - *n2ptr-- - borrow; - if (val < 0) - { - val += BASE; - borrow = 1; - } - else - borrow = 0; - *diffptr-- = val; - } - } - - /* Now do the equal length scale and integer parts. */ - - for (count = 0; count < min_len + min_scale; count++) - { - val = *n1ptr-- - *n2ptr-- - borrow; - if (val < 0) - { - val += BASE; - borrow = 1; - } - else - borrow = 0; - *diffptr-- = val; - } - - /* If n1 has more digits then n2, we now do that subtract. */ - if (diff_len != min_len) - { - for (count = diff_len - min_len; count > 0; count--) - { - val = *n1ptr-- - borrow; - if (val < 0) - { - val += BASE; - borrow = 1; - } - else - borrow = 0; - *diffptr-- = val; - } - } - - /* Clean up and return. */ - _bc_rm_leading_zeros (diff); - return diff; -} - - -/* Here is the full subtract routine that takes care of negative numbers. - N2 is subtracted from N1 and the result placed in RESULT. SCALE_MIN - is the minimum scale for the result. */ - -void -bc_sub (n1, n2, result, scale_min) - bc_num n1, n2, *result; - int scale_min; -{ - bc_num diff = NULL; - int cmp_res; - int res_scale; - - if (n1->n_sign != n2->n_sign) - { - diff = _bc_do_add (n1, n2, scale_min); - diff->n_sign = n1->n_sign; - } - else - { - /* subtraction must be done. */ - /* Compare magnitudes. */ - cmp_res = _bc_do_compare (n1, n2, FALSE, FALSE); - switch (cmp_res) - { - case -1: - /* n1 is less than n2, subtract n1 from n2. */ - diff = _bc_do_sub (n2, n1, scale_min); - diff->n_sign = (n2->n_sign == PLUS ? MINUS : PLUS); - break; - case 0: - /* They are equal! return zero! */ - res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale)); - diff = bc_new_num (1, res_scale); - memset (diff->n_value, 0, res_scale+1); - break; - case 1: - /* n2 is less than n1, subtract n2 from n1. */ - diff = _bc_do_sub (n1, n2, scale_min); - diff->n_sign = n1->n_sign; - break; - } - } - - /* Clean up and return. */ - bc_free_num (result); - *result = diff; -} - - -/* Here is the full add routine that takes care of negative numbers. - N1 is added to N2 and the result placed into RESULT. SCALE_MIN - is the minimum scale for the result. */ - -void -bc_add (n1, n2, result, scale_min) - bc_num n1, n2, *result; - int scale_min; -{ - bc_num sum = NULL; - int cmp_res; - int res_scale; - - if (n1->n_sign == n2->n_sign) - { - sum = _bc_do_add (n1, n2, scale_min); - sum->n_sign = n1->n_sign; - } - else - { - /* subtraction must be done. */ - cmp_res = _bc_do_compare (n1, n2, FALSE, FALSE); /* Compare magnitudes. */ - switch (cmp_res) - { - case -1: - /* n1 is less than n2, subtract n1 from n2. */ - sum = _bc_do_sub (n2, n1, scale_min); - sum->n_sign = n2->n_sign; - break; - case 0: - /* They are equal! return zero with the correct scale! */ - res_scale = MAX (scale_min, MAX(n1->n_scale, n2->n_scale)); - sum = bc_new_num (1, res_scale); - memset (sum->n_value, 0, res_scale+1); - break; - case 1: - /* n2 is less than n1, subtract n2 from n1. */ - sum = _bc_do_sub (n1, n2, scale_min); - sum->n_sign = n1->n_sign; - } - } - - /* Clean up and return. */ - bc_free_num (result); - *result = sum; -} - -/* Recursive vs non-recursive multiply crossover ranges. */ -#if defined(MULDIGITS) -#include "muldigits.h" -#else -#define MUL_BASE_DIGITS 80 -#endif - -int mul_base_digits = MUL_BASE_DIGITS; -#define MUL_SMALL_DIGITS mul_base_digits/4 - -/* Multiply utility routines */ - -static bc_num -new_sub_num (length, scale, value) - int length, scale; - char *value; -{ - bc_num temp; - - if (_bc_Free_list != NULL) { - temp = _bc_Free_list; - _bc_Free_list = temp->n_next; - } else { - temp = (bc_num) malloc (sizeof(bc_struct)); - if (temp == NULL) bc_out_of_memory (); - } - temp->n_sign = PLUS; - temp->n_len = length; - temp->n_scale = scale; - temp->n_refs = 1; - temp->n_ptr = NULL; - temp->n_value = value; - return temp; -} - -static void -_bc_simp_mul (bc_num n1, int n1len, bc_num n2, int n2len, bc_num *prod, - int full_scale) -{ - char *n1ptr, *n2ptr, *pvptr; - char *n1end, *n2end; /* To the end of n1 and n2. */ - int indx, sum, prodlen; - - prodlen = n1len+n2len+1; - - *prod = bc_new_num (prodlen, 0); - - n1end = (char *) (n1->n_value + n1len - 1); - n2end = (char *) (n2->n_value + n2len - 1); - pvptr = (char *) ((*prod)->n_value + prodlen - 1); - sum = 0; - - /* Here is the loop... */ - for (indx = 0; indx < prodlen-1; indx++) - { - n1ptr = (char *) (n1end - MAX(0, indx-n2len+1)); - n2ptr = (char *) (n2end - MIN(indx, n2len-1)); - while ((n1ptr >= n1->n_value) && (n2ptr <= n2end)) - sum += *n1ptr-- * *n2ptr++; - *pvptr-- = sum % BASE; - sum = sum / BASE; - } - *pvptr = sum; -} - - -/* A special adder/subtractor for the recursive divide and conquer - multiply algorithm. Note: if sub is called, accum must - be larger that what is being subtracted. Also, accum and val - must have n_scale = 0. (e.g. they must look like integers. *) */ -static void -_bc_shift_addsub (bc_num accum, bc_num val, int shift, int sub) -{ - signed char *accp, *valp; - int count, carry; - - count = val->n_len; - if (val->n_value[0] == 0) - count--; - assert (accum->n_len+accum->n_scale >= shift+count); - - /* Set up pointers and others */ - accp = (signed char *)(accum->n_value + - accum->n_len + accum->n_scale - shift - 1); - valp = (signed char *)(val->n_value + val->n_len - 1); - carry = 0; - - if (sub) { - /* Subtraction, carry is really borrow. */ - while (count--) { - *accp -= *valp-- + carry; - if (*accp < 0) { - carry = 1; - *accp-- += BASE; - } else { - carry = 0; - accp--; - } - } - while (carry) { - *accp -= carry; - if (*accp < 0) - *accp-- += BASE; - else - carry = 0; - } - } else { - /* Addition */ - while (count--) { - *accp += *valp-- + carry; - if (*accp > (BASE-1)) { - carry = 1; - *accp-- -= BASE; - } else { - carry = 0; - accp--; - } - } - while (carry) { - *accp += carry; - if (*accp > (BASE-1)) - *accp-- -= BASE; - else - carry = 0; - } - } -} - -/* Recursive divide and conquer multiply algorithm. - Based on - Let u = u0 + u1*(b^n) - Let v = v0 + v1*(b^n) - Then uv = (B^2n+B^n)*u1*v1 + B^n*(u1-u0)*(v0-v1) + (B^n+1)*u0*v0 - - B is the base of storage, number of digits in u1,u0 close to equal. -*/ -static void -_bc_rec_mul (bc_num u, int ulen, bc_num v, int vlen, bc_num *prod, - int full_scale) -{ - bc_num u0, u1, v0, v1; - int u0len, v0len; - bc_num m1, m2, m3, d1, d2; - int n, prodlen, m1zero; - int d1len, d2len; - - /* Base case? */ - if ((ulen+vlen) < mul_base_digits - || ulen < MUL_SMALL_DIGITS - || vlen < MUL_SMALL_DIGITS ) { - _bc_simp_mul (u, ulen, v, vlen, prod, full_scale); - return; - } - - /* Calculate n -- the u and v split point in digits. */ - n = (MAX(ulen, vlen)+1) / 2; - - /* Split u and v. */ - if (ulen < n) { - u1 = bc_copy_num (_zero_); - u0 = new_sub_num (ulen,0, u->n_value); - } else { - u1 = new_sub_num (ulen-n, 0, u->n_value); - u0 = new_sub_num (n, 0, u->n_value+ulen-n); - } - if (vlen < n) { - v1 = bc_copy_num (_zero_); - v0 = new_sub_num (vlen,0, v->n_value); - } else { - v1 = new_sub_num (vlen-n, 0, v->n_value); - v0 = new_sub_num (n, 0, v->n_value+vlen-n); - } - _bc_rm_leading_zeros (u1); - _bc_rm_leading_zeros (u0); - u0len = u0->n_len; - _bc_rm_leading_zeros (v1); - _bc_rm_leading_zeros (v0); - v0len = v0->n_len; - - m1zero = bc_is_zero(u1) || bc_is_zero(v1); - - /* Calculate sub results ... */ - - bc_init_num(&d1); - bc_init_num(&d2); - bc_sub (u1, u0, &d1, 0); - d1len = d1->n_len; - bc_sub (v0, v1, &d2, 0); - d2len = d2->n_len; - - - /* Do recursive multiplies and shifted adds. */ - if (m1zero) - m1 = bc_copy_num (_zero_); - else - _bc_rec_mul (u1, u1->n_len, v1, v1->n_len, &m1, 0); - - if (bc_is_zero(d1) || bc_is_zero(d2)) - m2 = bc_copy_num (_zero_); - else - _bc_rec_mul (d1, d1len, d2, d2len, &m2, 0); - - if (bc_is_zero(u0) || bc_is_zero(v0)) - m3 = bc_copy_num (_zero_); - else - _bc_rec_mul (u0, u0->n_len, v0, v0->n_len, &m3, 0); - - /* Initialize product */ - prodlen = ulen+vlen+1; - *prod = bc_new_num(prodlen, 0); - - if (!m1zero) { - _bc_shift_addsub (*prod, m1, 2*n, 0); - _bc_shift_addsub (*prod, m1, n, 0); - } - _bc_shift_addsub (*prod, m3, n, 0); - _bc_shift_addsub (*prod, m3, 0, 0); - _bc_shift_addsub (*prod, m2, n, d1->n_sign != d2->n_sign); - - /* Now clean up! */ - bc_free_num (&u1); - bc_free_num (&u0); - bc_free_num (&v1); - bc_free_num (&m1); - bc_free_num (&v0); - bc_free_num (&m2); - bc_free_num (&m3); - bc_free_num (&d1); - bc_free_num (&d2); -} - -/* The multiply routine. N2 times N1 is put int PROD with the scale of - the result being MIN(N2 scale+N1 scale, MAX (SCALE, N2 scale, N1 scale)). - */ - -void -bc_multiply (n1, n2, prod, scale) - bc_num n1, n2, *prod; - int scale; -{ - bc_num pval; - int len1, len2; - int full_scale, prod_scale; - - /* Initialize things. */ - len1 = n1->n_len + n1->n_scale; - len2 = n2->n_len + n2->n_scale; - full_scale = n1->n_scale + n2->n_scale; - prod_scale = MIN(full_scale,MAX(scale,MAX(n1->n_scale,n2->n_scale))); - - /* Do the multiply */ - _bc_rec_mul (n1, len1, n2, len2, &pval, full_scale); - - /* Assign to prod and clean up the number. */ - pval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS ); - pval->n_value = pval->n_ptr; - pval->n_len = len2 + len1 + 1 - full_scale; - pval->n_scale = prod_scale; - _bc_rm_leading_zeros (pval); - if (bc_is_zero (pval)) - pval->n_sign = PLUS; - bc_free_num (prod); - *prod = pval; -} - -/* Some utility routines for the divide: First a one digit multiply. - NUM (with SIZE digits) is multiplied by DIGIT and the result is - placed into RESULT. It is written so that NUM and RESULT can be - the same pointers. */ - -static void -_one_mult (num, size, digit, result) - unsigned char *num; - int size, digit; - unsigned char *result; -{ - int carry, value; - unsigned char *nptr, *rptr; - - if (digit == 0) - memset (result, 0, size); - else - { - if (digit == 1) - memcpy (result, num, size); - else - { - /* Initialize */ - nptr = (unsigned char *) (num+size-1); - rptr = (unsigned char *) (result+size-1); - carry = 0; - - while (size-- > 0) - { - value = *nptr-- * digit + carry; - *rptr-- = value % BASE; - carry = value / BASE; - } - - if (carry != 0) *rptr = carry; - } - } -} - - -/* The full division routine. This computes N1 / N2. It returns - 0 if the division is ok and the result is in QUOT. The number of - digits after the decimal point is SCALE. It returns -1 if division - by zero is tried. The algorithm is found in Knuth Vol 2. p237. */ - -int -bc_divide (n1, n2, quot, scale) - bc_num n1, n2, *quot; - int scale; -{ - bc_num qval; - unsigned char *num1, *num2; - unsigned char *ptr1, *ptr2, *n2ptr, *qptr; - int scale1, val; - unsigned int len1, len2, scale2, qdigits, extra, count; - unsigned int qdig, qguess, borrow, carry; - unsigned char *mval; - char zero; - unsigned int norm; - - /* Test for divide by zero. */ - if (bc_is_zero (n2)) return -1; - - /* Test for divide by 1. If it is we must truncate. */ - if (n2->n_scale == 0) - { - if (n2->n_len == 1 && *n2->n_value == 1) - { - qval = bc_new_num (n1->n_len, scale); - qval->n_sign = (n1->n_sign == n2->n_sign ? PLUS : MINUS); - memset (&qval->n_value[n1->n_len],0,scale); - memcpy (qval->n_value, n1->n_value, - n1->n_len + MIN(n1->n_scale,scale)); - bc_free_num (quot); - *quot = qval; - } - } - - /* Set up the divide. Move the decimal point on n1 by n2's scale. - Remember, zeros on the end of num2 are wasted effort for dividing. */ - scale2 = n2->n_scale; - n2ptr = (unsigned char *) n2->n_value+n2->n_len+scale2-1; - while ((scale2 > 0) && (*n2ptr-- == 0)) scale2--; - - len1 = n1->n_len + scale2; - scale1 = n1->n_scale - scale2; - if (scale1 < scale) - extra = scale - scale1; - else - extra = 0; - num1 = (unsigned char *) malloc (n1->n_len+n1->n_scale+extra+2); - if (num1 == NULL) bc_out_of_memory(); - memset (num1, 0, n1->n_len+n1->n_scale+extra+2); - memcpy (num1+1, n1->n_value, n1->n_len+n1->n_scale); - - len2 = n2->n_len + scale2; - num2 = (unsigned char *) malloc (len2+1); - if (num2 == NULL) bc_out_of_memory(); - memcpy (num2, n2->n_value, len2); - *(num2+len2) = 0; - n2ptr = num2; - while (*n2ptr == 0) - { - n2ptr++; - len2--; - } - - /* Calculate the number of quotient digits. */ - if (len2 > len1+scale) - { - qdigits = scale+1; - zero = TRUE; - } - else - { - zero = FALSE; - if (len2>len1) - qdigits = scale+1; /* One for the zero integer part. */ - else - qdigits = len1-len2+scale+1; - } - - /* Allocate and zero the storage for the quotient. */ - qval = bc_new_num (qdigits-scale,scale); - memset (qval->n_value, 0, qdigits); - - /* Allocate storage for the temporary storage mval. */ - mval = (unsigned char *) malloc (len2+1); - if (mval == NULL) bc_out_of_memory (); - - /* Now for the full divide algorithm. */ - if (!zero) - { - /* Normalize */ - norm = 10 / ((int)*n2ptr + 1); - if (norm != 1) - { - _one_mult (num1, len1+scale1+extra+1, norm, num1); - _one_mult (n2ptr, len2, norm, n2ptr); - } - - /* Initialize divide loop. */ - qdig = 0; - if (len2 > len1) - qptr = (unsigned char *) qval->n_value+len2-len1; - else - qptr = (unsigned char *) qval->n_value; - - /* Loop */ - while (qdig <= len1+scale-len2) - { - /* Calculate the quotient digit guess. */ - if (*n2ptr == num1[qdig]) - qguess = 9; - else - qguess = (num1[qdig]*10 + num1[qdig+1]) / *n2ptr; - - /* Test qguess. */ - if (n2ptr[1]*qguess > - (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10 - + num1[qdig+2]) - { - qguess--; - /* And again. */ - if (n2ptr[1]*qguess > - (num1[qdig]*10 + num1[qdig+1] - *n2ptr*qguess)*10 - + num1[qdig+2]) - qguess--; - } - - /* Multiply and subtract. */ - borrow = 0; - if (qguess != 0) - { - *mval = 0; - _one_mult (n2ptr, len2, qguess, mval+1); - ptr1 = (unsigned char *) num1+qdig+len2; - ptr2 = (unsigned char *) mval+len2; - for (count = 0; count < len2+1; count++) - { - val = (int) *ptr1 - (int) *ptr2-- - borrow; - if (val < 0) - { - val += 10; - borrow = 1; - } - else - borrow = 0; - *ptr1-- = val; - } - } - - /* Test for negative result. */ - if (borrow == 1) - { - qguess--; - ptr1 = (unsigned char *) num1+qdig+len2; - ptr2 = (unsigned char *) n2ptr+len2-1; - carry = 0; - for (count = 0; count < len2; count++) - { - val = (int) *ptr1 + (int) *ptr2-- + carry; - if (val > 9) - { - val -= 10; - carry = 1; - } - else - carry = 0; - *ptr1-- = val; - } - if (carry == 1) *ptr1 = (*ptr1 + 1) % 10; - } - - /* We now know the quotient digit. */ - *qptr++ = qguess; - qdig++; - } - } - - /* Clean up and return the number. */ - qval->n_sign = ( n1->n_sign == n2->n_sign ? PLUS : MINUS ); - if (bc_is_zero (qval)) qval->n_sign = PLUS; - _bc_rm_leading_zeros (qval); - bc_free_num (quot); - *quot = qval; - - /* Clean up temporary storage. */ - free (mval); - free (num1); - free (num2); - - return 0; /* Everything is OK. */ -} - - -/* Division *and* modulo for numbers. This computes both NUM1 / NUM2 and - NUM1 % NUM2 and puts the results in QUOT and REM, except that if QUOT - is NULL then that store will be omitted. - */ - -int -bc_divmod (num1, num2, quot, rem, scale) - bc_num num1, num2, *quot, *rem; - int scale; -{ - bc_num quotient = NULL; - bc_num temp; - int rscale; - - /* Check for correct numbers. */ - if (bc_is_zero (num2)) return -1; - - /* Calculate final scale. */ - rscale = MAX (num1->n_scale, num2->n_scale+scale); - bc_init_num(&temp); - - /* Calculate it. */ - bc_divide (num1, num2, &temp, scale); - if (quot) - quotient = bc_copy_num (temp); - bc_multiply (temp, num2, &temp, rscale); - bc_sub (num1, temp, rem, rscale); - bc_free_num (&temp); - - if (quot) - { - bc_free_num (quot); - *quot = quotient; - } - - return 0; /* Everything is OK. */ -} - - -/* Modulo for numbers. This computes NUM1 % NUM2 and puts the - result in RESULT. */ - -int -bc_modulo (num1, num2, result, scale) - bc_num num1, num2, *result; - int scale; -{ - return bc_divmod (num1, num2, NULL, result, scale); -} - -/* Raise BASE to the EXPO power, reduced modulo MOD. The result is - placed in RESULT. If a EXPO is not an integer, - only the integer part is used. */ - -int -bc_raisemod (base, expo, mod, result, scale) - bc_num base, expo, mod, *result; - int scale; -{ - bc_num power, exponent, parity, temp; - int rscale; - - /* Check for correct numbers. */ - if (bc_is_zero(mod)) return -1; - if (bc_is_neg(expo)) return -1; - - /* Set initial values. */ - power = bc_copy_num (base); - exponent = bc_copy_num (expo); - temp = bc_copy_num (_one_); - bc_init_num(&parity); - - /* Check the base for scale digits. */ - if (base->n_scale != 0) - bc_rt_warn ("non-zero scale in base"); - - /* Check the exponent for scale digits. */ - if (exponent->n_scale != 0) - { - bc_rt_warn ("non-zero scale in exponent"); - bc_divide (exponent, _one_, &exponent, 0); /*truncate */ - } - - /* Check the modulus for scale digits. */ - if (mod->n_scale != 0) - bc_rt_warn ("non-zero scale in modulus"); - - /* Do the calculation. */ - rscale = MAX(scale, base->n_scale); - while ( !bc_is_zero(exponent) ) - { - (void) bc_divmod (exponent, _two_, &exponent, &parity, 0); - if ( !bc_is_zero(parity) ) - { - bc_multiply (temp, power, &temp, rscale); - (void) bc_modulo (temp, mod, &temp, scale); - } - - bc_multiply (power, power, &power, rscale); - (void) bc_modulo (power, mod, &power, scale); - } - - /* Assign the value. */ - bc_free_num (&power); - bc_free_num (&exponent); - bc_free_num (result); - *result = temp; - return 0; /* Everything is OK. */ -} - -/* Raise NUM1 to the NUM2 power. The result is placed in RESULT. - Maximum exponent is LONG_MAX. If a NUM2 is not an integer, - only the integer part is used. */ - -void -bc_raise (num1, num2, result, scale) - bc_num num1, num2, *result; - int scale; -{ - bc_num temp, power; - long exponent; - int rscale; - int pwrscale; - int calcscale; - char neg; - - /* Check the exponent for scale digits and convert to a long. */ - if (num2->n_scale != 0) - bc_rt_warn ("non-zero scale in exponent"); - exponent = bc_num2long (num2); - if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0)) - bc_rt_error ("exponent too large in raise"); - - /* Special case if exponent is a zero. */ - if (exponent == 0) - { - bc_free_num (result); - *result = bc_copy_num (_one_); - return; - } - - /* Other initializations. */ - if (exponent < 0) - { - neg = TRUE; - exponent = -exponent; - rscale = scale; - } - else - { - neg = FALSE; - rscale = MIN (num1->n_scale*exponent, MAX(scale, num1->n_scale)); - } - - /* Set initial value of temp. */ - power = bc_copy_num (num1); - pwrscale = num1->n_scale; - while ((exponent & 1) == 0) - { - pwrscale = 2*pwrscale; - bc_multiply (power, power, &power, pwrscale); - exponent = exponent >> 1; - } - temp = bc_copy_num (power); - calcscale = pwrscale; - exponent = exponent >> 1; - - /* Do the calculation. */ - while (exponent > 0) - { - pwrscale = 2*pwrscale; - bc_multiply (power, power, &power, pwrscale); - if ((exponent & 1) == 1) { - calcscale = pwrscale + calcscale; - bc_multiply (temp, power, &temp, calcscale); - } - exponent = exponent >> 1; - } - - /* Assign the value. */ - if (neg) - { - bc_divide (_one_, temp, result, rscale); - bc_free_num (&temp); - } - else - { - bc_free_num (result); - *result = temp; - if ((*result)->n_scale > rscale) - (*result)->n_scale = rscale; - } - bc_free_num (&power); -} - -/* Take the square root NUM and return it in NUM with SCALE digits - after the decimal place. */ - -int -bc_sqrt (num, scale) - bc_num *num; - int scale; -{ - int rscale, cmp_res, done; - int cscale; - bc_num guess, guess1, point5, diff; - - /* Initial checks. */ - cmp_res = bc_compare (*num, _zero_); - if (cmp_res < 0) - return 0; /* error */ - else - { - if (cmp_res == 0) - { - bc_free_num (num); - *num = bc_copy_num (_zero_); - return 1; - } - } - cmp_res = bc_compare (*num, _one_); - if (cmp_res == 0) - { - bc_free_num (num); - *num = bc_copy_num (_one_); - return 1; - } - - /* Initialize the variables. */ - rscale = MAX (scale, (*num)->n_scale); - bc_init_num(&guess); - bc_init_num(&guess1); - bc_init_num(&diff); - point5 = bc_new_num (1,1); - point5->n_value[1] = 5; - - - /* Calculate the initial guess. */ - if (cmp_res < 0) - { - /* The number is between 0 and 1. Guess should start at 1. */ - guess = bc_copy_num (_one_); - cscale = (*num)->n_scale; - } - else - { - /* The number is greater than 1. Guess should start at 10^(exp/2). */ - bc_int2num (&guess,10); - - bc_int2num (&guess1,(*num)->n_len); - bc_multiply (guess1, point5, &guess1, 0); - guess1->n_scale = 0; - bc_raise (guess, guess1, &guess, 0); - bc_free_num (&guess1); - cscale = 3; - } - - /* Find the square root using Newton's algorithm. */ - done = FALSE; - while (!done) - { - bc_free_num (&guess1); - guess1 = bc_copy_num (guess); - bc_divide (*num, guess, &guess, cscale); - bc_add (guess, guess1, &guess, 0); - bc_multiply (guess, point5, &guess, cscale); - bc_sub (guess, guess1, &diff, cscale+1); - if (bc_is_near_zero (diff, cscale)) - { - if (cscale < rscale+1) - cscale = MIN (cscale*3, rscale+1); - else - done = TRUE; - } - } - - /* Assign the number and clean up. */ - bc_free_num (num); - bc_divide (guess,_one_,num,rscale); - bc_free_num (&guess); - bc_free_num (&guess1); - bc_free_num (&point5); - bc_free_num (&diff); - return 1; -} - - -/* The following routines provide output for bcd numbers package - using the rules of POSIX bc for output. */ - -/* This structure is used for saving digits in the conversion process. */ -typedef struct stk_rec { - long digit; - struct stk_rec *next; -} stk_rec; - -/* The reference string for digits. */ -static char ref_str[] = "0123456789ABCDEF"; - - -/* A special output routine for "multi-character digits." Exactly - SIZE characters must be output for the value VAL. If SPACE is - non-zero, we must output one space before the number. OUT_CHAR - is the actual routine for writing the characters. */ - -void -bc_out_long (val, size, space, out_char) - long val; - int size, space; -#ifdef __STDC__ - void (*out_char)(int); -#else - void (*out_char)(); -#endif -{ - char digits[40]; - int len, ix; - - if (space) (*out_char) (' '); - sprintf (digits, "%ld", val); - len = strlen (digits); - while (size > len) - { - (*out_char) ('0'); - size--; - } - for (ix=0; ix < len; ix++) - (*out_char) (digits[ix]); -} - -/* Output of a bcd number. NUM is written in base O_BASE using OUT_CHAR - as the routine to do the actual output of the characters. */ - -void -bc_out_num (num, o_base, out_char, leading_zero) - bc_num num; - int o_base; -#ifdef __STDC__ - void (*out_char)(int); -#else - void (*out_char)(); -#endif - int leading_zero; -{ - char *nptr; - int 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 (bc_is_zero (num)) - (*out_char) ('0'); - else - if (o_base == 10) - { - /* The number is in base 10, do it the fast way. */ - nptr = num->n_value; - if (num->n_len > 1 || *nptr != 0) - for (index=num->n_len; index>0; index--) - (*out_char) (BCD_CHAR(*nptr++)); - else - nptr++; - - if (leading_zero && bc_is_zero (num)) - (*out_char) ('0'); - - /* Now the fraction. */ - if (num->n_scale > 0) - { - (*out_char) ('.'); - for (index=0; indexn_scale; index++) - (*out_char) (BCD_CHAR(*nptr++)); - } - } - else - { - /* special case ... */ - if (leading_zero && bc_is_zero (num)) - (*out_char) ('0'); - - /* The number is some other base. */ - digits = NULL; - bc_init_num (&int_part); - bc_divide (num, _one_, &int_part, 0); - bc_init_num (&frac_part); - bc_init_num (&cur_dig); - bc_init_num (&base); - bc_sub (num, int_part, &frac_part, 0); - /* Make the INT_PART and FRAC_PART positive. */ - int_part->n_sign = PLUS; - frac_part->n_sign = PLUS; - bc_int2num (&base, o_base); - bc_init_num (&max_o_digit); - bc_int2num (&max_o_digit, o_base-1); - - - /* Get the digits of the integer part and push them on a stack. */ - while (!bc_is_zero (int_part)) - { - bc_modulo (int_part, base, &cur_dig, 0); - temp = (stk_rec *) malloc (sizeof(stk_rec)); - if (temp == NULL) bc_out_of_memory(); - temp->digit = bc_num2long (cur_dig); - temp->next = digits; - digits = temp; - bc_divide (int_part, base, &int_part, 0); - } - - /* Print the digits on the stack. */ - if (digits != NULL) - { - /* Output the digits. */ - while (digits != NULL) - { - temp = digits; - digits = digits->next; - if (o_base <= 16) - (*out_char) (ref_str[ (int) temp->digit]); - else - bc_out_long (temp->digit, max_o_digit->n_len, 1, out_char); - free (temp); - } - } - - /* Get and print the digits of the fraction part. */ - if (num->n_scale > 0) - { - (*out_char) ('.'); - pre_space = 0; - t_num = bc_copy_num (_one_); - while (t_num->n_len <= num->n_scale) { - bc_multiply (frac_part, base, &frac_part, num->n_scale); - fdigit = bc_num2long (frac_part); - bc_int2num (&int_part, fdigit); - bc_sub (frac_part, int_part, &frac_part, 0); - if (o_base <= 16) - (*out_char) (ref_str[fdigit]); - else { - bc_out_long (fdigit, max_o_digit->n_len, pre_space, out_char); - pre_space = 1; - } - bc_multiply (t_num, base, &t_num, 0); - } - bc_free_num (&t_num); - } - - /* Clean up. */ - bc_free_num (&int_part); - bc_free_num (&frac_part); - bc_free_num (&base); - bc_free_num (&cur_dig); - bc_free_num (&max_o_digit); - } -} -/* Convert a number NUM to a long. The function returns only the integer - part of the number. For numbers that are too large to represent as - a long, this function returns a zero. This can be detected by checking - the NUM for zero after having a zero returned. */ - -long -bc_num2long (num) - bc_num num; -{ - long val; - char *nptr; - int index; - - /* Extract the int value, ignore the fraction. */ - val = 0; - nptr = num->n_value; - for (index=num->n_len; (index>0) && (val<=(LONG_MAX/BASE)); index--) - val = val*BASE + *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); -} - - -/* Convert an integer VAL to a bc number NUM. */ - -void -bc_int2num (num, val) - bc_num *num; - int val; -{ - char buffer[30]; - char *bptr, *vptr; - int ix = 1; - char neg = 0; - - /* Sign. */ - if (val < 0) - { - neg = 1; - val = -val; - } - - /* Get things going. */ - bptr = buffer; - *bptr++ = val % BASE; - val = val / BASE; - - /* Extract remaining digits. */ - while (val != 0) - { - *bptr++ = val % BASE; - val = val / BASE; - ix++; /* Count the digits. */ - } - - /* Make the number. */ - bc_free_num (num); - *num = bc_new_num (ix, 0); - if (neg) (*num)->n_sign = MINUS; - - /* Assign the digits. */ - vptr = (*num)->n_value; - while (ix-- > 0) - *vptr++ = *--bptr; -} - -/* Convert a numbers to a string. Base 10 only.*/ - -char -*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) bc_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; indexn_scale; index++) - *sptr++ = BCD_CHAR(*nptr++); - } - - /* Terminate the string and return it! */ - *sptr = '\0'; - return (str); -} -/* Convert strings to bc numbers. Base 10 only.*/ - -void -bc_str2num (num, str, scale) - bc_num *num; - char *str; - int scale; -{ - int digits, strscale; - char *ptr, *nptr; - char zero_int; - - /* Prepare num. */ - bc_free_num (num); - - /* Check for valid number and count digits. */ - ptr = str; - digits = 0; - strscale = 0; - zero_int = FALSE; - if ( (*ptr == '+') || (*ptr == '-')) ptr++; /* Sign */ - while (*ptr == '0') ptr++; /* Skip leading zeros. */ - while (isdigit((int)*ptr)) ptr++, digits++; /* digits */ - if (*ptr == '.') ptr++; /* decimal point */ - while (isdigit((int)*ptr)) ptr++, strscale++; /* digits */ - if ((*ptr != '\0') || (digits+strscale == 0)) - { - *num = bc_copy_num (_zero_); - return; - } - - /* Adjust numbers and allocate storage and initialize fields. */ - strscale = MIN(strscale, scale); - if (digits == 0) - { - zero_int = TRUE; - digits = 1; - } - *num = bc_new_num (digits, strscale); - - /* Build the whole number. */ - ptr = str; - if (*ptr == '-') - { - (*num)->n_sign = MINUS; - ptr++; - } - else - { - (*num)->n_sign = PLUS; - if (*ptr == '+') ptr++; - } - while (*ptr == '0') ptr++; /* Skip leading zeros. */ - nptr = (*num)->n_value; - if (zero_int) - { - *nptr++ = 0; - digits = 0; - } - for (;digits > 0; digits--) - *nptr++ = CH_VAL(*ptr++); - - - /* Build the fractional part. */ - if (strscale > 0) - { - ptr++; /* skip the decimal point! */ - for (;strscale > 0; strscale--) - *nptr++ = CH_VAL(*ptr++); - } -} - -/* pn prints the number NUM in base 10. */ - -static void -out_char (int c) -{ - putchar(c); -} - - -void -pn (num) - bc_num num; -{ - bc_out_num (num, 10, out_char, 0); - out_char ('\n'); -} - - -/* pv prints a character array as if it was a string of bcd digits. */ -void -pv (name, num, len) - char *name; - unsigned char *num; - int len; -{ - int i; - printf ("%s=", name); - for (i=0; i -#include -#include "number.h" -#ifndef VARARGS -#include -#else -#include -#endif - -/* from number.c ... */ -extern int mul_base_digits; -/* extern int mul_small_digits; */ -extern bc_num _one_; - -/* global variables */ -int test_n = 1000; -int test_time = 30 * CLOCKS_PER_SEC; /* 30 seconds */ - -/* Other things for number.c. */ -int std_only; - -void -out_of_memory() -{ - fprintf (stderr, "Fatal error: Out of memory for malloc.\n"); - exit (1); -} - -/* Runtime error will print a message and stop the machine. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -rt_error (char *mesg, ...) -#else -void -rt_error (mesg) - char *mesg; -#endif -#else -void -rt_error (mesg, va_alist) - char *mesg; -#endif -{ - va_list args; - char error_mesg [255]; - -#ifndef VARARGS - va_start (args, mesg); -#else - va_start (args); -#endif - vsprintf (error_mesg, mesg, args); - va_end (args); - - fprintf (stderr, "Runtime error: %s\n", error_mesg); -} - -/* A runtime warning tells of some action taken by the processor that - may change the program execution but was not enough of a problem - to stop the execution. */ - -#ifndef VARARGS -#ifdef __STDC__ -void -rt_warn (char *mesg, ...) -#else -void -rt_warn (mesg) - char *mesg; -#endif -#else -void -rt_warn (mesg, va_alist) - char *mesg; -#endif -{ - va_list args; - char error_mesg [255]; - -#ifndef VARARGS - va_start (args, mesg); -#else - va_start (args); -#endif - vsprintf (error_mesg, mesg, args); - va_end (args); - - fprintf (stderr, "Runtime warning: %s\n", error_mesg); -} - -void -out_char (int ch) -{ - putchar (ch); -} - -/* Time stuff !!! */ - -int -timeit ( bc_num a, bc_num b, int *n) -{ - clock_t first; - int i, res; - bc_num c; - - bc_init_num (&c); - first = clock(); - *n = 0; - do { - for (i=0; i 1) - if (strcmp (argv[1], "-d") == 0) - debug = 1; - - bc_init_numbers(); - bc_init_num (&ten); - bc_init_num (&num); - bc_init_num (&expo); - bc_init_num (&big); - bc_int2num (&ten, 10); - - if (debug) - fprintf (stderr, "Timings are for %d multiplies\n" - "Minimum time is %d seconds\n", test_n, - test_time/CLOCKS_PER_SEC); - - /* Two of the same size */ - min = 10; - max = 500; - - if (debug) - fprintf (stderr, "Testing numbers of the same length.\n"); - - while (min < max) { - mid = (min+max)/2; - if (debug) fprintf (stderr,"Checking %d...\n", mid); - - bc_int2num (&expo, mid); - bc_raise (ten, expo, &num, 0); - bc_sub (num, _one_, &num, 0); - - mul_base_digits = 2*mid+1; - t1 = timeit (num, num, &n1); - permul1 = (float)t1/(float)n1; - - mul_base_digits = 2*mid-1; - t2 = timeit (num, num, &n2); - permul2 = (float)t2/(float)n2; - - if (permul1 < permul2) - min = mid+1; - else - max = mid-1; - - if (debug) { - fprintf (stderr, "n1 = %d :: n2 = %d\n", n1, n2); - fprintf (stderr, "p1 = %f :: p2 = %f\n", permul1, permul2); - } - } - - if (debug) - fprintf (stderr, "Base digits crossover at %d digits\n", min); - printf ("#define MUL_BASE_DIGITS %d\n", 2*min); - - -#if 0 - mul_base_digits = min; - - /* Small one times a big one. */ - - smallsize = min/2; - bc_int2num (&expo, smallsize); - bc_raise (ten, expo, &big, 0); - bc_sub (num, _one_, &big, 0); - - min = min / 2; - max = 500; - - if (debug) - fprintf (stderr, "Testing numbers of the different length.\n"); - - while (min < max) { - mid = (min+max)/2; - if (debug) fprintf (stderr, "Checking %d...\n", mid); - - bc_int2num (&expo, mid-smallsize); - bc_raise (ten, expo, &num, 0); - bc_sub (num, _one_, &num, 0); - - mul_small_digits = mid+1; - t1 = timeit (big, num, &n1); - permul1 = (float)t1/(float)n1; - - mul_small_digits = mid-1; - t2 = timeit (big, num, &n2); - permul2 = (float)t2/(float)n2; - - if (permul1 < permul2) - min = mid+1; - else - max = mid-1; - - if (debug) { - fprintf (stderr, "n1 = %d :: n2 = %d\n", n1, n2); - fprintf (stderr, "p1 = %f :: p2 = %f\n", permul1, permul2); - } - } - - if (debug) - fprintf (stderr, "Non equal digits crossover at %d total digits\n", min); - printf ("#define MUL_SMALL_DIGITS = %d\n", min); - -#endif - - return 0; -} diff --git a/src/bin/bc/lib/vfprintf.c b/src/bin/bc/lib/vfprintf.c deleted file mode 100644 index ad53d0c37a..0000000000 --- a/src/bin/bc/lib/vfprintf.c +++ /dev/null @@ -1,31 +0,0 @@ -/* vfprintf.c -- this was provided for minix. It may not - work on any other system. */ - -#include "config.h" -#ifndef HAVE_VPRINTF -#ifndef HAVE_DOPRINT - #error need vfprintf() or doprint() -#else - -#ifdef HAVE_LIB_H -#include -#endif -#ifdef HAVE_STDARG_H -#include -#endif -#ifdef HAVE_STDIO_H -#include -#endif - -int vfprintf(file, format, argp) -FILE *file; -_CONST char *format; -va_list argp; -{ - _doprintf(file, format, argp); - if (testflag(file, PERPRINTF)) fflush(file); - return 0; -} - -#endif /* HAVE_DOPRINT */ -#endif /* !HAVE_VFPRINTF */