diff --git a/gnu/usr.bin/dc/COPYING b/gnu/usr.bin/dc/COPYING deleted file mode 100644 index e77696ae8ddf..000000000000 --- a/gnu/usr.bin/dc/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - 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) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/gnu/usr.bin/dc/Makefile b/gnu/usr.bin/dc/Makefile index a20cee3683dd..a723055672d5 100644 --- a/gnu/usr.bin/dc/Makefile +++ b/gnu/usr.bin/dc/Makefile @@ -1,10 +1,26 @@ -PROG= dc -SRCS= dc-array.c dc-eval.c dc-misc.c dc-number.c dc-stack.c dc-string.c number.c -CFLAGS+=-I${.CURDIR} -I${.CURDIR}/../bc -D_POSIX_SOURCE -DPADD= ${LIBM} -LDADD= -lm +# Makefile copyright Andreas Klemm 1998 +# +# $Id$ + +.include "${.CURDIR}/../Makefile.inc" + +.PATH: ${.CURDIR}/../../../contrib/bc/dc \ + ${.CURDIR}/../../../contrib/bc/lib \ + ${.CURDIR}/../../../contrib/bc/doc + +PROG= dc +SRCS= array.c dc.c eval.c misc.c numeric.c stack.c string.c \ + getopt.c getopt1.c number.c +MAN1= dc.1 + +CFLAGS+= -DHAVE_VPRINTF=1 -DSTDC_HEADERS=1 -DHAVE_ISGRAPH=1 \ + -DHAVE_LIMITS_H=1 -DHAVE_STDARG_H=1 -DHAVE_STDDEF_H=1 \ + -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 \ + -I${.CURDIR}/../../../contrib/bc/h -I. + +DPADD= ${LIBM} +LDADD= -lm + SUBDIR+= doc -.PATH: ${.CURDIR}/../bc - .include diff --git a/gnu/usr.bin/dc/config.h b/gnu/usr.bin/dc/config.h new file mode 100644 index 000000000000..abdc7024855e --- /dev/null +++ b/gnu/usr.bin/dc/config.h @@ -0,0 +1,5 @@ +/* config.h */ +#ifndef __STDC__ +#define VARARGS +#endif +#define YYTEXT_POINTER 1 diff --git a/gnu/usr.bin/dc/dc-array.c b/gnu/usr.bin/dc/dc-array.c deleted file mode 100644 index dd16ed9e8ee7..000000000000 --- a/gnu/usr.bin/dc/dc-array.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * implement arrays for dc - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -/* This module is the only one that knows what arrays look like. */ - -#include "config.h" - -#include /* "dc-proto.h" wants this */ -#include -#include "dc.h" -#include "dc-proto.h" -#include "dc-regdef.h" - -/* what's most useful: quick access or sparse arrays? */ -/* I'll go with sparse arrays for now */ -struct dc_array { - int Index; - dc_data value; - struct dc_array *next; -}; -typedef struct dc_array dc_array; - -/* I can find no reason not to place arrays in their own namespace... */ -static dc_array *dc_array_register[DC_REGCOUNT]; - - -/* initialize the arrays to their initial values */ -void -dc_array_init DC_DECLVOID() -{ - int i; - - for (i=0; iIndex < Index){ - prev = cur; - cur = cur->next; - } - if (cur && cur->Index == Index){ - if (cur->value.dc_type == DC_NUMBER) - dc_free_num(&cur->value.v.number); - else if (cur->value.dc_type == DC_STRING) - dc_free_str(&cur->value.v.string); - else - dc_garbage(" in array", array_id); - cur->value = value; - }else{ - newentry = dc_malloc(sizeof *newentry); - newentry->Index = Index; - newentry->value = value; - newentry->next = cur; - if (prev) - prev->next = newentry; - else - dc_array_register[array_id] = newentry; - } -} - -/* retrieve a dup of a value from array_id[Index] */ -/* A zero value is returned if the specified value is unintialized. */ -dc_data -dc_array_get DC_DECLARG((array_id, Index)) - int array_id DC_DECLSEP - int Index DC_DECLEND -{ - dc_array *cur; - - for (cur=dc_array_register[regmap(array_id)]; cur; cur=cur->next) - if (cur->Index == Index) - return dc_dup(cur->value); - return dc_int2data(0); -} diff --git a/gnu/usr.bin/dc/dc-eval.c b/gnu/usr.bin/dc/dc-eval.c deleted file mode 100644 index e368caafafad..000000000000 --- a/gnu/usr.bin/dc/dc-eval.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * evaluate the dc language, from a FILE* or a string - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -/* This is the only module which knows about the dc input language */ - -#include "config.h" - -#include -#include -#include "dc.h" -#include "dc-proto.h" - -typedef enum { - DC_OKAY, /* 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 rescan_stdin's value - */ - DC_INT, /* caller needs to parse a dc_num from input stream */ - DC_STR, /* caller needs to parse a dc_str from input stream */ - DC_SYSTEM, /* caller needs to run a system() on next input line */ - DC_COMMENT, /* caller needs to skip to the next input line */ - - DC_EOF_ERROR /* unexpected end of input; abort current eval */ -} dc_status; - -static int dc_ibase=10; /* input base, 2 <= dc_ibase <= DC_IBASE_MAX */ -static int dc_obase=10; /* output base, 2 <= dc_obase */ -static int dc_scale=0; /* scale (see user documentaton) */ - -/* forward reference */ -static dc_status dc_evalstr DC_PROTO((dc_data)); - -/* for Quitting evaluations */ -static int unwind_depth=0; - -/* if true, active Quit will not exit program */ -static dc_boolean unwind_noexit=DC_FALSE; - -/* if true, stdin has been mucked with, dc_evalfile() needs to resyncronize */ -static dc_boolean rescan_stdin=DC_FALSE; - - -/* 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 dc_status -dc_eval_and_free_str DC_DECLARG((string)) - dc_data string DC_DECLEND -{ - dc_status status; - - status = dc_evalstr(string); - if (string.dc_type == DC_STRING) - dc_free_str(&string.v.string); - return status; -} - - -/* dc_func does the grunt work of figuring out what each input - * character means; used by both dc_evalstr and dc_evalfile - * - * c -> the "current" input character under consideration - * peekc -> the lookahead input character - */ -static dc_status -dc_func DC_DECLARG((c, peekc)) - int c DC_DECLSEP - int peekc DC_DECLEND -{ - /* we occasionally need these for temporary data */ - /* Despite the GNU coding standards, it is much easier - * to have these decared 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 '^': /* exponientiation of the top two stack elements */ - dc_binop(dc_exp, dc_scale); - break; - case '<': - /* eval register named by peekc if - * less-than holds for top two stack elements - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_cmpop() < 0) - if (dc_register_get(peekc, &datum) == DC_SUCCESS) - if (dc_eval_and_free_str(datum) == DC_QUIT) - return DC_QUIT; - return DC_EATONE; - case '=': - /* eval register named by peekc if - * equal-to holds for top two stack elements - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_cmpop() == 0) - if (dc_register_get(peekc, &datum) == DC_SUCCESS) - if (dc_eval_and_free_str(datum) == DC_QUIT) - return DC_QUIT; - return DC_EATONE; - case '>': - /* eval register named by peekc if - * greater-than holds for top two stack elements - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_cmpop() > 0) - if (dc_register_get(peekc, &datum) == DC_SUCCESS) - if (dc_eval_and_free_str(datum) == DC_QUIT) - return DC_QUIT; - return DC_EATONE; - case '?': /* read a lnie from standard-input and eval it */ - for (c=peekc; c=='\n'; c=getc(stdin)) - ; - ungetc(c, stdin); - if (dc_eval_and_free_str(dc_readstring(stdin, '\n', '\n')) == DC_QUIT) - return DC_QUIT; - rescan_stdin = DC_TRUE; - return DC_OKAY; - case '[': /* read to balancing ']' into a dc_str */ - return DC_STR; - case '!': /* read to newline and call system() on resulting string */ - return DC_SYSTEM; - case '#': /* comment; skip remainder of current line */ - return DC_COMMENT; - - case 'c': /* clear whole stack */ - dc_clear_stack(); - break; - case 'd': /* duplicate the datum on the top of stack */ - if (dc_top_of_stack(&datum) == DC_SUCCESS) - dc_push(dc_dup(datum)); - break; - case 'f': /* print list of all stack items */ - dc_printall(dc_obase); - break; - case 'i': /* set input base to value on top of stack */ - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = 0; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); - if ( ! (2 <= tmpint && tmpint <= DC_IBASE_MAX) ) - fprintf(stderr, - "%s: input base must be a number \ -between 2 and %d (inclusive)\n", - progname, DC_IBASE_MAX); - else - dc_ibase = tmpint; - } - break; - case 'k': /* set scale to value on top of stack */ - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = -1; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); - if ( ! (tmpint >= 0) ) - fprintf(stderr, - "%s: scale must be a nonnegative number\n", - progname); - else - dc_scale = tmpint; - } - break; - case 'l': /* "load" -- push value on top of register stack named - * by peekc onto top of evaluation stack; does not - * modify the register stack - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_register_get(peekc, &datum) == DC_SUCCESS) - dc_push(datum); - return DC_EATONE; - case 'o': /* set output base to value on top of stack */ - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = 0; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); - if ( ! (tmpint > 1) ) - fprintf(stderr, - "%s: output base must be a number greater than 1\n", - progname); - else - dc_obase = tmpint; - } - break; - case 'p': /* print the datum on the top of stack */ - if (dc_top_of_stack(&datum) == DC_SUCCESS) - dc_print(datum, dc_obase); - break; - case 'q': /* quit two levels of evaluation, posibly exiting program */ - unwind_depth = 2; - unwind_noexit = DC_FALSE; - return DC_QUIT; - case 's': /* "store" -- replace top of register stack named - * by peekc with the value popped from the top - * of the evaluation stack - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_pop(&datum) == DC_SUCCESS) - dc_register_set(peekc, datum); - return DC_EATONE; - case 'v': /* replace top of stack with its square root */ - if (dc_pop(&datum) == DC_SUCCESS){ - dc_num tmpnum; - if (datum.dc_type != DC_NUMBER){ - fprintf(stderr, - "%s: square root of nonnumeric attempted\n", - progname); - }else if (dc_sqrt(datum.v.number, dc_scale, &tmpnum) == DC_SUCCESS){ - dc_free_num(&datum.v.number); - datum.v.number = tmpnum; - dc_push(datum); - } - } - break; - case 'x': /* eval the datum popped from top of stack */ - if (dc_pop(&datum) == DC_SUCCESS){ - if (datum.dc_type == DC_STRING){ - if (dc_eval_and_free_str(datum) == DC_QUIT) - return DC_QUIT; - }else if (datum.dc_type == DC_NUMBER){ - dc_push(datum); - }else{ - dc_garbage("at top of stack", -1); - } - } - break; - case 'z': /* push the current stack depth onto the top of stack */ - dc_push(dc_int2data(dc_tell_stackdepth())); - break; - - case 'I': /* push the current input base onto the stack */ - dc_push(dc_int2data(dc_ibase)); - break; - case 'K': /* push the current scale onto the stack */ - dc_push(dc_int2data(dc_scale)); - break; - case 'L': /* pop a value off of register stack named by peekc - * and push it onto the evaluation stack - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_register_pop(peekc, &datum) == DC_SUCCESS) - dc_push(datum); - return DC_EATONE; - case 'O': /* push the current output base onto the stack */ - dc_push(dc_int2data(dc_obase)); - break; - case 'P': /* print the value popped off of top-of-stack; - * do not add a trailing newline - */ - if (dc_pop(&datum) == DC_SUCCESS){ - if (datum.dc_type == DC_STRING) - dc_out_str(datum.v.string, DC_FALSE, DC_TRUE); - else if (datum.dc_type == DC_NUMBER) - dc_out_num(datum.v.number, dc_obase, DC_FALSE, DC_TRUE); - else - dc_garbage("at top of stack", -1); - } - break; - case 'Q': /* quit out of top-of-stack nested evals; - * pops value from stack; - * does not exit program (stops short if necessary) - */ - if (dc_pop(&datum) == DC_SUCCESS){ - unwind_depth = 0; - unwind_noexit = DC_TRUE; - if (datum.dc_type == DC_NUMBER) - unwind_depth = dc_num2int(datum.v.number, DC_TRUE); - if (unwind_depth > 0) - return DC_QUIT; - fprintf(stderr, - "%s: Q command requires a positive number\n", - progname); - } - break; - case 'S': /* pop a value off of the evaluation stack - * and push it onto the register stack named by peekc - */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_pop(&datum) == DC_SUCCESS) - dc_register_push(peekc, datum); - return DC_EATONE; - case 'X': /* replace the number on top-of-stack with its scale factor */ - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = 0; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_tell_scale(datum.v.number, DC_TRUE); - dc_push(dc_int2data(tmpint)); - } - break; - case 'Z': /* replace the datum on the top-of-stack with its length */ - if (dc_pop(&datum) == DC_SUCCESS) - dc_push(dc_int2data(dc_tell_length(datum, DC_TRUE))); - break; - - case ':': /* store into array */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = -1; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); - if (dc_pop(&datum) == DC_SUCCESS){ - if (tmpint < 0) - fprintf(stderr, - "%s: array index must be a nonnegative integer\n", - progname); - else - dc_array_set(peekc, tmpint, datum); - } - } - return DC_EATONE; - case ';': /* retreive from array */ - if (peekc == EOF) - return DC_EOF_ERROR; - if (dc_pop(&datum) == DC_SUCCESS){ - tmpint = -1; - if (datum.dc_type == DC_NUMBER) - tmpint = dc_num2int(datum.v.number, DC_TRUE); - if (tmpint < 0) - fprintf(stderr, - "%s: array index must be a nonnegative integer\n", - progname); - else - dc_push(dc_array_get(peekc, tmpint)); - } - return DC_EATONE; - - default: /* What did that user mean? */ - fprintf(stderr, "%s: ", progname); - dc_show_id(stdout, c, " unimplemented\n"); - break; - } - return DC_OKAY; -} - - -/* takes a string and evals it */ -static dc_status -dc_evalstr DC_DECLARG((string)) - dc_data string DC_DECLEND -{ - const char *s; - const char *end; - const char *p; - size_t len; - int c; - int peekc; - int count; - - if (string.dc_type != DC_STRING){ - fprintf(stderr, - "%s: eval called with non-string argument\n", - progname); - return DC_OKAY; - } - s = dc_str2charp(string.v.string); - end = s + dc_strlen(string.v.string); - while (s < end){ - c = *(const unsigned char *)s++; - peekc = EOF; - if (s < end) - peekc = *(const unsigned char *)s; - switch (dc_func(c, peekc)){ - case DC_OKAY: - break; - case DC_EATONE: - if (peekc != EOF) - ++s; - break; - case DC_QUIT: - if (unwind_depth > 0){ - --unwind_depth; - return DC_QUIT; - } - return DC_OKAY; - - case DC_INT: - input_str_string = s - 1; - dc_push(dc_getnum(input_str, dc_ibase, &peekc)); - s = input_str_string; - if (peekc != EOF) - --s; - break; - case DC_STR: - count = 1; - for (p=s; 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; - ++s; - break; - - case DC_EOF_ERROR: - fprintf(stderr, "%s: unexpected EOS\n", progname); - return DC_OKAY; - } - } - return DC_OKAY; -} - - -/* This is the main function of the whole DC program. - * Reads the file described by fp, calls dc_func to do - * the dirty work, and takes care of dc_func's shortcomings. - */ -int -dc_evalfile DC_DECLARG((fp)) - FILE *fp DC_DECLEND -{ - int c; - int peekc; - dc_data datum; - - for (c=getc(fp); c!=EOF; c=peekc){ - peekc = getc(fp); - rescan_stdin = DC_FALSE; - switch (dc_func(c, peekc)){ - case DC_OKAY: - if (rescan_stdin == DC_TRUE && 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 (rescan_stdin == DC_TRUE && fp == stdin) - peekc = getc(fp); - break; - - case DC_INT: - input_fil_fp = fp; - input_pushback = c; - ungetc(peekc, fp); - dc_push(dc_getnum(input_fil, dc_ibase, &peekc)); - break; - case DC_STR: - ungetc(peekc, fp); - datum = dc_readstring(fp, '[', ']'); - dc_push(datum); - peekc = getc(fp); - break; - case DC_SYSTEM: - ungetc(peekc, fp); - datum = dc_readstring(stdin, '\n', '\n'); - (void)dc_system(dc_str2charp(datum.v.string)); - dc_free_str(&datum.v.string); - peekc = getc(fp); - break; - case DC_COMMENT: - while (peekc!=EOF && peekc!='\n') - peekc = getc(fp); - if (peekc != EOF) - peekc = getc(fp); - break; - - case DC_EOF_ERROR: - fprintf(stderr, "%s: unexpected EOF\n", progname); - return DC_FAIL; - } - } - return DC_SUCCESS; -} diff --git a/gnu/usr.bin/dc/dc-misc.c b/gnu/usr.bin/dc/dc-misc.c deleted file mode 100644 index 6443c60ed552..000000000000 --- a/gnu/usr.bin/dc/dc-misc.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * implement the "dc" Desk Calculator language. - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -/* Written with strong hiding of implementation details - * in their own specialized modules. - */ -/* 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 -#include -#include -#include -#include "dc.h" -#include "dc-proto.h" - -#include "dc-version.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 */ - -/* your generic usage function */ -static void -usage DC_DECLARG((f)) - FILE *f DC_DECLEND -{ - fprintf(f, "Usage: %s [OPTION]\n", progname); - fprintf(f, " --help display this help and exit\n"); - fprintf(f, " --version output version information and exit\n"); -} - -/* returns a pointer to one past the last occurance of c in s, - * or s if c does not occur in s. - */ -static char * -r1bindex DC_DECLARG((s, c)) - char *s DC_DECLSEP - int c DC_DECLEND -{ - char *p = strrchr(s, c); - - if (!p) - return s; - return p + 1; -} - - -int -main DC_DECLARG((argc, argv)) - int argc DC_DECLSEP - char **argv DC_DECLEND -{ - progname = r1bindex(*argv, '/'); - if (argc>1 && strcmp(argv[1], "--version")==0){ - printf("%s\n", Version); - return EXIT_SUCCESS; - }else if (argc>1 && strcmp(argv[1], "--help")==0){ - usage(stdout); - return EXIT_SUCCESS; - }else if (argc==2 && strcmp(argv[1], "--")==0){ - /*just ignore it*/ - }else if (argc != 1){ - usage(stderr); - return EXIT_FAILURE; - } - - dc_math_init(); - dc_string_init(); - dc_register_init(); - dc_array_init(); - dc_evalfile(stdin); - return EXIT_SUCCESS; -} - - -/* print an "out of memory" diagnostic and exit program */ -void -dc_memfail DC_DECLVOID() -{ - fprintf(stderr, "%s: out of memory\n", progname); - exit(EXIT_FAILURE); -} - -/* malloc or die */ -void * -dc_malloc DC_DECLARG((len)) - size_t len DC_DECLEND -{ - void *result = malloc(len); - - if (!result) - dc_memfail(); - return result; -} - - -/* print the id in a human-understandable form - * fp is the output stream to place the output on - * id is the name of the register (or command) to be printed - * suffix is a modifier (such as "stack") to be printed - */ -void -dc_show_id DC_DECLARG((fp, id, suffix)) - FILE *fp DC_DECLSEP - int id DC_DECLSEP - const char *suffix DC_DECLEND -{ - if (isgraph(id)) - fprintf(fp, "'%c' (%#o)%s", id, id, suffix); - else - fprintf(fp, "%#o%s", id, suffix); -} - - -/* report that corrupt data has been detected; - * use the msg and regid (if nonnegative) to give information - * about where the garbage was found, - * - * will abort() so that a debugger might be used to help find - * the bug - */ -/* If this routine is called, then there is a bug in the code; - * i.e. it is _not_ a data or user error - */ -void -dc_garbage DC_DECLARG((msg, regid)) - const char *msg DC_DECLSEP - int regid DC_DECLEND -{ - if (regid < 0){ - fprintf(stderr, "%s: garbage %s\n", progname, msg); - }else{ - fprintf(stderr, "%s:%s register ", progname, msg); - dc_show_id(stderr, regid, " is garbage\n"); - } - abort(); -} - - -/* call system() with the passed string; - * if the string contains a newline, terminate the string - * there before calling system. - * Return a pointer to the first unused character in the string - * (i.e. past the '\n' if there was one, to the '\0' otherwise). - */ -const char * -dc_system DC_DECLARG((s)) - const char *s DC_DECLEND -{ - const char *p; - char *tmpstr; - size_t len; - - p = strchr(s, '\n'); - if (p){ - len = p - s; - tmpstr = dc_malloc(len + 1); - strncpy(tmpstr, s, len); - tmpstr[len] = '\0'; - system(tmpstr); - free(tmpstr); - return p + 1; - } - system(s); - return s + strlen(s); -} - - -/* print out the indicated value */ -void -dc_print DC_DECLARG((value, obase)) - dc_data value DC_DECLSEP - int obase DC_DECLEND -{ - if (value.dc_type == DC_NUMBER){ - dc_out_num(value.v.number, obase, DC_TRUE, DC_FALSE); - }else if (value.dc_type == DC_STRING){ - dc_out_str(value.v.string, DC_TRUE, DC_FALSE); - }else{ - dc_garbage("in data being printed", -1); - } -} - -/* return a duplicate of the passed value, regardless of type */ -dc_data -dc_dup DC_DECLARG((value)) - dc_data value DC_DECLEND -{ - if (value.dc_type!=DC_NUMBER && value.dc_type!=DC_STRING) - dc_garbage("in value being duplicated", -1); - if (value.dc_type == DC_NUMBER) - return dc_dup_num(value.v.number); - /*else*/ - return dc_dup_str(value.v.string); -} diff --git a/gnu/usr.bin/dc/dc-number.c b/gnu/usr.bin/dc/dc-number.c deleted file mode 100644 index 80075065aae8..000000000000 --- a/gnu/usr.bin/dc/dc-number.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * interface dc to the bc numeric routines - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -/* This should be the only module that knows the internals of type dc_num */ - -#include "config.h" - -#include -#include -#include "bcdefs.h" -#include "proto.h" -#include "global.h" -#include "dc.h" -#include "dc-proto.h" - -/* convert an opaque dc_num into a real bc_num */ -#define CastNum(x) ((bc_num)(x)) - -/* add two dc_nums, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_add DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - init_num((bc_num *)result); - bc_add(CastNum(a), CastNum(b), (bc_num *)result); - return DC_SUCCESS; -} - -/* subtract two dc_nums, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_sub DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - init_num((bc_num *)result); - bc_sub(CastNum(a), CastNum(b), (bc_num *)result); - return DC_SUCCESS; -} - -/* multiply two dc_nums, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_mul DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - init_num((bc_num *)result); - bc_multiply(CastNum(a), CastNum(b), (bc_num *)result, kscale); - return DC_SUCCESS; -} - -/* divide two dc_nums, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_div DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - init_num((bc_num *)result); - if (bc_divide(CastNum(a), CastNum(b), (bc_num *)result, kscale)){ - fprintf(stderr, "%s: divide by zero\n", progname); - return DC_DOMAIN_ERROR; - } - return DC_SUCCESS; -} - -/* place the reminder of dividing a by b into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_rem DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - init_num((bc_num *)result); - if (bc_modulo(CastNum(a), CastNum(b), (bc_num *)result, kscale)){ - fprintf(stderr, "%s: remainder by zero\n", progname); - return DC_DOMAIN_ERROR; - } - return DC_SUCCESS; -} - -/* place the result of exponentiationg a by b into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_exp DC_DECLARG((a, b, kscale, result)) - dc_num a DC_DECLSEP - dc_num b DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - init_num((bc_num *)result); - bc_raise(CastNum(a), CastNum(b), (bc_num *)result, kscale); - return DC_SUCCESS; -} - -/* take the square root of the value, place into *result; - * return DC_SUCCESS on success, DC_DOMAIN_ERROR on domain error - */ -int -dc_sqrt DC_DECLARG((value, kscale, result)) - dc_num value DC_DECLSEP - int kscale DC_DECLSEP - dc_num *result DC_DECLEND -{ - bc_num tmp; - - tmp = copy_num(CastNum(value)); - if (!bc_sqrt(&tmp, kscale)){ - fprintf(stderr, "%s: square root of negative number\n", progname); - free_num(&tmp); - return DC_DOMAIN_ERROR; - } - *((bc_num *)result) = tmp; - return DC_SUCCESS; -} - -/* compare dc_nums a and b; - * return a negative value if a < b; - * return a positive value if a > b; - * return zero value if a == b - */ -int -dc_compare DC_DECLARG((a, b)) - dc_num a DC_DECLSEP - dc_num b DC_DECLEND -{ - return bc_compare(CastNum(a), CastNum(b)); -} - -/* attempt to convert a dc_num to its corresponding int value - * If discard_flag is true then deallocate the value after use. - */ -int -dc_num2int DC_DECLARG((value, discard_flag)) - dc_num value DC_DECLSEP - dc_boolean discard_flag DC_DECLEND -{ - long result; - - result = num2long(CastNum(value)); - if (discard_flag) - dc_free_num(&value); - return (int)result; -} - -/* convert a C integer value into a dc_num */ -/* For convenience of the caller, package the dc_num - * into a dc_data result. - */ -dc_data -dc_int2data DC_DECLARG((value)) - int value DC_DECLEND -{ - dc_data result; - - init_num((bc_num *)&result.v.number); - int2num((bc_num *)&result.v.number, value); - result.dc_type = DC_NUMBER; - return result; -} - -/* get a dc_num from some input stream; - * input is a function which knows how to read the desired input stream - * ibase is the input base (2<=ibase<=DC_IBASE_MAX) - * *readahead will be set to the readahead character consumed while - * looking for the end-of-number - */ -/* For convenience of the caller, package the dc_num - * into a dc_data result. - */ -dc_data -dc_getnum DC_DECLARG((input, ibase, readahead)) - int (*input) DC_PROTO((void)) DC_DECLSEP - int ibase DC_DECLSEP - int *readahead DC_DECLEND -{ - bc_num base; - bc_num result; - bc_num build; - bc_num tmp; - bc_num divisor; - dc_data full_result; - int negative = 0; - int digit; - int decimal; - int c; - - init_num(&tmp); - init_num(&build); - init_num(&base); - result = copy_num(_zero_); - int2num(&base, ibase); - c = (*input)(); - while (isspace(c)) - c = (*input)(); - if (c == '_' || c == '-'){ - negative = c; - c = (*input)(); - }else if (c == '+'){ - c = (*input)(); - } - while (isspace(c)) - c = (*input)(); - for (;;){ - if (isdigit(c)) - digit = c - '0'; - else if ('A' <= c && c <= 'F') - digit = 10 + c - 'A'; - else - break; - c = (*input)(); - int2num(&tmp, digit); - bc_multiply(result, base, &result, 0); - bc_add(result, tmp, &result); - } - if (c == '.'){ - free_num(&build); - free_num(&tmp); - divisor = copy_num(_one_); - build = copy_num(_zero_); - decimal = 0; - for (;;){ - c = (*input)(); - if (isdigit(c)) - digit = c - '0'; - else if ('A' <= c && c <= 'F') - digit = 10 + c - 'A'; - else - break; - int2num(&tmp, digit); - bc_multiply(build, base, &build, 0); - bc_add(build, tmp, &build); - bc_multiply(divisor, base, &divisor, 0); - ++decimal; - } - bc_divide(build, divisor, &build, decimal); - bc_add(result, build, &result); - } - /* Final work. */ - if (negative) - bc_sub(_zero_, result, &result); - - free_num(&tmp); - free_num(&build); - free_num(&base); - if (readahead) - *readahead = c; - full_result.v.number = (dc_num)result; - full_result.dc_type = DC_NUMBER; - return full_result; -} - - -/* return the "length" of the number */ -int -dc_numlen DC_DECLARG((value)) - dc_num value DC_DECLEND -{ - bc_num num = CastNum(value); - - /* is this right??? */ - return num->n_len + num->n_scale; -} - -/* return the scale factor of the passed dc_num - * If discard_flag is true then deallocate the value after use. - */ -int -dc_tell_scale DC_DECLARG((value, discard_flag)) - dc_num value DC_DECLSEP - dc_boolean discard_flag DC_DECLEND -{ - int kscale; - - kscale = CastNum(value)->n_scale; - if (discard_flag) - dc_free_num(&value); - return kscale; -} - - -/* initialize the math subsystem */ -void -dc_math_init DC_DECLVOID() -{ - init_numbers(); -} - -/* print out a dc_num in output base obase to stdout; - * if newline is true, terminate output with a '\n'; - * if discard_flag is true then deallocate the value after use - */ -void -dc_out_num DC_DECLARG((value, obase, newline, discard_flag)) - dc_num value DC_DECLSEP - int obase DC_DECLSEP - dc_boolean newline DC_DECLSEP - dc_boolean discard_flag DC_DECLEND -{ - out_num(CastNum(value), obase, out_char); - if (newline) - out_char('\n'); - if (discard_flag) - dc_free_num(&value); -} - - -/* deallocate an instance of a dc_num */ -void -dc_free_num DC_DECLARG((value)) - dc_num *value DC_DECLEND -{ - free_num((bc_num *)value); -} - -/* return a duplicate of the number in the passed value */ -/* The mismatched data types forces the caller to deal with - * bad dc_type'd dc_data values, and makes it more convenient - * for the caller to not have to do the grunge work of setting - * up a dc_type result. - */ -dc_data -dc_dup_num DC_DECLARG((value)) - dc_num value DC_DECLEND -{ - dc_data result; - - ++CastNum(value)->n_refs; - result.v.number = value; - result.dc_type = DC_NUMBER; - return result; -} - - - -/*---------------------------------------------------------------------------\ -| The rest of this file consists of stubs for bc routines called by number.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. | -\---------------------------------------------------------------------------*/ - -#include - -#if __STDC__ -# 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 "\". */ - -void -out_char (ch) - char ch; -{ - - if (ch == '\n') - { - out_col = 0; - putchar ('\n'); - } - else - { - out_col++; - if (out_col == 70) - { - putchar ('\\'); - putchar ('\n'); - out_col = 1; - } - putchar (ch); - } -} - -/* Malloc could not get enought memory. */ - -void -out_of_memory() -{ - dc_memfail(); -} - -/* Runtime error will print a message and stop the machine. */ - -#if __STDC__ -void -rt_error (char *mesg, ...) -#else -void -rt_error (mesg, va_alist) - char *mesg; - va_dcl -#endif -{ - va_list args; - char error_mesg [255]; - -#if __STDC__ - 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. */ - -#if __STDC__ -void -rt_warn (char *mesg, ...) -#else -void -rt_warn (mesg, va_alist) - char *mesg; - va_dcl -#endif -{ - va_list args; - char error_mesg [255]; - -#if __STDC__ - va_start (args, mesg); -#else - va_start (args); -#endif - vsprintf (error_mesg, mesg, args); - va_end (args); - - fprintf (stderr, "Runtime warning: %s\n", error_mesg); -} diff --git a/gnu/usr.bin/dc/dc-proto.h b/gnu/usr.bin/dc/dc-proto.h deleted file mode 100644 index 97d7aff43003..000000000000 --- a/gnu/usr.bin/dc/dc-proto.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * prototypes of all externally visible dc functions - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -extern const char *dc_str2charp DC_PROTO((dc_str)); -extern const char *dc_system DC_PROTO((const char *)); -extern void *dc_malloc DC_PROTO((size_t)); - -extern void dc_array_set DC_PROTO((int, int, dc_data)); -extern void dc_array_init DC_PROTO((void)); -extern void dc_binop DC_PROTO((int (*)(dc_num, dc_num, int, dc_num *), int)); -extern void dc_clear_stack DC_PROTO((void)); -extern void dc_free_num DC_PROTO((dc_num *)); -extern void dc_free_str DC_PROTO((dc_str *)); -extern void dc_garbage DC_PROTO((const char *, int)); -extern void dc_math_init DC_PROTO((void)); -extern void dc_memfail DC_PROTO((void)); -extern void dc_out_num DC_PROTO((dc_num, int, dc_boolean, dc_boolean)); -extern void dc_out_str DC_PROTO((dc_str, dc_boolean, dc_boolean)); -extern void dc_print DC_PROTO((dc_data, int)); -extern void dc_printall DC_PROTO((int)); -extern void dc_push DC_PROTO((dc_data)); -extern void dc_register_init DC_PROTO((void)); -extern void dc_register_push DC_PROTO((int, dc_data)); -extern void dc_register_set DC_PROTO((int, dc_data)); -extern void dc_show_id DC_PROTO((FILE *, int, const char *)); -extern void dc_string_init DC_PROTO((void)); - -extern int dc_cmpop DC_PROTO((void)); -extern int dc_compare DC_PROTO((dc_num, dc_num)); -extern int dc_evalfile DC_PROTO((FILE *)); -extern int dc_num2int DC_PROTO((dc_num, dc_boolean)); -extern int dc_numlen DC_PROTO((dc_num)); -extern int dc_pop DC_PROTO((dc_data *)); -extern int dc_register_get DC_PROTO((int, dc_data *)); -extern int dc_register_pop DC_PROTO((int, dc_data *)); -extern int dc_tell_length DC_PROTO((dc_data, dc_boolean)); -extern int dc_tell_scale DC_PROTO((dc_num, dc_boolean)); -extern int dc_tell_stackdepth DC_PROTO((void)); -extern int dc_top_of_stack DC_PROTO((dc_data *)); - -extern size_t dc_strlen DC_PROTO((dc_str)); - -extern dc_data dc_array_get DC_PROTO((int, int)); -extern dc_data dc_dup DC_PROTO((dc_data)); -extern dc_data dc_dup_num DC_PROTO((dc_num)); -extern dc_data dc_dup_str DC_PROTO((dc_str)); -extern dc_data dc_getnum DC_PROTO((int (*)(void), int, int *)); -extern dc_data dc_int2data DC_PROTO((int)); -extern dc_data dc_makestring DC_PROTO((const char *, size_t)); -extern dc_data dc_readstring DC_PROTO((FILE *, int , int)); - -extern int dc_add DC_PROTO((dc_num, dc_num, int, dc_num *)); -extern int dc_div DC_PROTO((dc_num, dc_num, int, dc_num *)); -extern int dc_exp DC_PROTO((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/gnu/usr.bin/dc/dc-regdef.h b/gnu/usr.bin/dc/dc-regdef.h deleted file mode 100644 index 41422059050d..000000000000 --- a/gnu/usr.bin/dc/dc-regdef.h +++ /dev/null @@ -1,38 +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.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -#include - -/* 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/gnu/usr.bin/dc/dc-stack.c b/gnu/usr.bin/dc/dc-stack.c deleted file mode 100644 index 76e61b393430..000000000000 --- a/gnu/usr.bin/dc/dc-stack.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * implement stack functions for dc - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -/* This module is the only one that knows what stacks (both the - * regular evaluation stack and the named register stacks) - * look like. - */ - -#include "config.h" - -#include -#include -#include "dc.h" -#include "dc-proto.h" -#include "dc-regdef.h" - -/* an oft-used error message: */ -#define Empty_Stack fprintf(stderr, "%s: stack empty\n", progname) - - -/* simple linked-list implementaion suffices: */ -struct dc_list { - dc_data value; - struct dc_list *link; -}; -typedef struct dc_list dc_list; - -/* the anonymous evaluation stack */ -static dc_list *dc_stack=NULL; - -/* the named register stacks */ -static dc_list *dc_register[DC_REGCOUNT]; - - -/* allocate a new dc_list item */ -static dc_list * -dc_alloc DC_DECLVOID() -{ - dc_list *result; - - result = dc_malloc(sizeof *result); - result->value.dc_type = DC_UNINITIALIZED; - result->link = NULL; - return result; -} - - -/* check that there are two numbers on top of the stack, - * then call op with the popped numbers. Construct a dc_data - * value from the dc_num returned by op and push it - * on the stack. - * If the op call doesn't return DC_SUCCESS, then leave the stack - * unmodified. - */ -void -dc_binop DC_DECLARG((op, kscale)) - int (*op)DC_PROTO((dc_num, dc_num, int, dc_num *)) DC_DECLSEP - int kscale DC_DECLEND -{ - dc_data a; - dc_data b; - dc_data r; - - if (!dc_stack || !dc_stack->link){ - Empty_Stack; - return; - } - if (dc_stack->value.dc_type!=DC_NUMBER - || dc_stack->link->value.dc_type!=DC_NUMBER){ - fprintf(stderr, "%s: non-numeric value\n", progname); - return; - } - (void)dc_pop(&b); - (void)dc_pop(&a); - if ((*op)(a.v.number, b.v.number, kscale, &r.v.number) == DC_SUCCESS){ - r.dc_type = DC_NUMBER; - dc_push(r); - dc_free_num(&a.v.number); - dc_free_num(&b.v.number); - }else{ - /* op failed; restore the stack */ - dc_push(a); - dc_push(b); - } -} - -/* check that there are two numbers on top of the stack, - * then call 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; -} - - -/* 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); - free(n); - } - dc_stack = NULL; -} - -/* push a value onto the evaluation stack */ -void -dc_push DC_DECLARG((value)) - dc_data value DC_DECLEND -{ - dc_list *n = dc_alloc(); - - if (value.dc_type!=DC_NUMBER && value.dc_type!=DC_STRING) - dc_garbage("in data being pushed", -1); - n->value = value; - n->link = dc_stack; - dc_stack = n; -} - -/* push a value onto the named register stack */ -void -dc_register_push DC_DECLARG((stackid, value)) - int stackid DC_DECLSEP - dc_data value DC_DECLEND -{ - dc_list *n = dc_alloc(); - - stackid = regmap(stackid); - n->value = value; - n->link = dc_register[stackid]; - dc_register[stackid] = n; -} - -/* set *result to the value on the top of the evaluation stack */ -/* The caller is responsible for duplicating the value if it - * is to be maintained as anything more than a transient identity. - * - * DC_FAIL is returned if the stack is empty (and *result unchanged), - * DC_SUCCESS is returned otherwise - */ -int -dc_top_of_stack DC_DECLARG((result)) - dc_data *result DC_DECLEND -{ - if (!dc_stack){ - Empty_Stack; - return DC_FAIL; - } - if (dc_stack->value.dc_type!=DC_NUMBER - && dc_stack->value.dc_type!=DC_STRING) - dc_garbage("at top of stack", -1); - *result = dc_stack->value; - return DC_SUCCESS; -} - -/* set *result to a dup of the value on the top of the named register stack */ -/* - * DC_FAIL is returned if the named stack is empty (and *result unchanged), - * DC_SUCCESS is returned otherwise - */ -int -dc_register_get DC_DECLARG((regid, result)) - int regid DC_DECLSEP - dc_data *result DC_DECLEND -{ - dc_list *r; - - regid = regmap(regid); - r = dc_register[regid]; - if ( ! r ){ - fprintf(stderr, "%s: register ", progname); - dc_show_id(stderr, regid, " is empty\n"); - return DC_FAIL; - } - *result = dc_dup(r->value); - return DC_SUCCESS; -} - -/* set the top of the named register stack to the indicated value */ -/* If the named stack is empty, craft a stack entry to enter the - * value into. - */ -void -dc_register_set DC_DECLARG((regid, value)) - int regid DC_DECLSEP - dc_data value DC_DECLEND -{ - dc_list *r; - - regid = regmap(regid); - r = dc_register[regid]; - if ( ! r ) - dc_register[regid] = dc_alloc(); - else if (r->value.dc_type == DC_NUMBER) - dc_free_num(&r->value.v.number); - else if (r->value.dc_type == DC_STRING) - dc_free_str(&r->value.v.string); - else - dc_garbage("", regid); - dc_register[regid]->value = value; -} - -/* pop from the evaluation stack - * - * DC_FAIL is returned if the stack is empty (and *result unchanged), - * DC_SUCCESS is returned otherwise - */ -int -dc_pop DC_DECLARG((result)) - dc_data *result DC_DECLEND -{ - dc_list *r; - - r = dc_stack; - if (!r){ - Empty_Stack; - return DC_FAIL; - } - if (r->value.dc_type!=DC_NUMBER && r->value.dc_type!=DC_STRING) - dc_garbage("at top of stack", -1); - *result = r->value; - dc_stack = r->link; - free(r); - return DC_SUCCESS; -} - -/* pop from the named register stack - * - * DC_FAIL is returned if the named stack is empty (and *result unchanged), - * DC_SUCCESS is returned otherwise - */ -int -dc_register_pop DC_DECLARG((stackid, result)) - int stackid DC_DECLSEP - dc_data *result DC_DECLEND -{ - dc_list *r; - - stackid = regmap(stackid); - r = dc_register[stackid]; - if (!r){ - fprintf(stderr, "%s: stack register ", progname); - dc_show_id(stderr, stackid, " is empty\n"); - return DC_FAIL; - } - if (r->value.dc_type!=DC_NUMBER && r->value.dc_type!=DC_STRING) - dc_garbage(" stack", stackid); - *result = r->value; - dc_register[stackid] = r->link; - free(r); - return DC_SUCCESS; -} - - -/* tell how many entries are currently on the evaluation stack */ -int -dc_tell_stackdepth DC_DECLVOID() -{ - dc_list *n; - int depth=0; - - for (n=dc_stack; n; n=n->link) - ++depth; - return depth; -} - - -/* return the length of the indicated data value; - * if discard_flag is true, the deallocate the value when done - * - * The definition of a datum's length is deligated to the - * appropriate module. - */ -int -dc_tell_length DC_DECLARG((value, discard_flag)) - dc_data value DC_DECLSEP - dc_boolean discard_flag DC_DECLEND -{ - int length; - - if (value.dc_type == DC_NUMBER){ - length = dc_numlen(value.v.number); - if (discard_flag == DC_TRUE) - dc_free_num(&value.v.number); - } else if (value.dc_type == DC_STRING) { - length = dc_strlen(value.v.string); - if (discard_flag == DC_TRUE) - dc_free_str(&value.v.string); - } else { - dc_garbage("in tell_length", -1); - /*NOTREACHED*/ - length = 0; /*just to suppress spurious compiler warnings*/ - } - return length; -} - - - -/* print out all of the values on the evaluation stack */ -void -dc_printall DC_DECLARG((obase)) - int obase DC_DECLEND -{ - dc_list *n; - - for (n=dc_stack; n; n=n->link) - dc_print(n->value, obase); -} diff --git a/gnu/usr.bin/dc/dc-string.c b/gnu/usr.bin/dc/dc-string.c deleted file mode 100644 index 262cb03b5e29..000000000000 --- a/gnu/usr.bin/dc/dc-string.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * implement string functions for dc - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -/* This should be the only module that knows the internals of type dc_string */ - -#include "config.h" - -#include -#include -#include -#include -#include "dc.h" -#include "dc-proto.h" - -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; - - ++((struct dc_string *)value)->s_refs; - result.v.string = value; - result.dc_type = DC_STRING; - return result; -} - -/* free an instance of a dc_str value */ -void -dc_free_str DC_DECLARG((value)) - dc_str *value DC_DECLEND -{ - struct dc_string *string = *value; - - if (--string->s_refs < 1){ - free(string->s_ptr); - free(string); - } -} - -/* Output a dc_str value. - * Add a trailing newline if "newline" is set. - * Free the value after use if discard_flag is set. - */ -void -dc_out_str DC_DECLARG((value, newline, discard_flag)) - dc_str value DC_DECLSEP - dc_boolean newline DC_DECLSEP - dc_boolean discard_flag DC_DECLEND -{ - struct dc_string *string = value; - - printf("%s", string->s_ptr); - if (newline == DC_TRUE) - printf("\n"); - if (discard_flag == DC_TRUE) - dc_free_str(&value); -} - -/* make a copy of a string (base s, length len) - * into a dc_str value; return a dc_data result - * with this value - */ -dc_data -dc_makestring DC_DECLARG((s, len)) - const char *s DC_DECLSEP - size_t len DC_DECLEND -{ - dc_data result; - struct dc_string *string; - - string = dc_malloc(sizeof *string); - string->s_ptr = dc_malloc(len+1); - memcpy(string->s_ptr, s, len); - string->s_ptr[len] = '\0'; /* nul terminated for those who need it */ - string->s_len = len; - string->s_refs = 1; - result.v.string = string; - result.dc_type = DC_STRING; - return result; -} - -/* read a dc_str value from FILE *fp; - * if ldelim == rdelim, then read until a ldelim char or EOF is reached; - * if ldelim != rdelim, then read until a matching rdelim for the - * (already eaten) first ldelim is read. - * Return a dc_data result with the dc_str value as its contents. - */ -dc_data -dc_readstring DC_DECLARG((fp, ldelim, rdelim)) - FILE *fp DC_DECLSEP - int ldelim DC_DECLSEP - int rdelim DC_DECLEND -{ - static char *line_buf = NULL; /* a buffer to build the string in */ - static size_t buflen = 0; /* the current size of line_buf */ - int depth=1; - int c; - char *p; - const char *end; - - if (!line_buf){ - /* initial buflen should be large enough to handle most cases */ - buflen = 2016; - line_buf = dc_malloc(buflen); - } - p = line_buf; - end = line_buf + buflen; - for (;;){ - c = getc(fp); - if (c == EOF) - break; - else if (c == rdelim && --depth < 1) - break; - else if (c == ldelim) - ++depth; - if (p >= end){ - ptrdiff_t offset = p - line_buf; - /* buflen increment should be big enough - * to avoid execessive reallocs: - */ - buflen += 2048; - line_buf = realloc(line_buf, buflen); - if (!line_buf) - dc_memfail(); - p = line_buf + offset; - end = line_buf + buflen; - } - *p++ = c; - } - return dc_makestring(line_buf, (size_t)(p-line_buf)); -} - -/* return the base pointer of the dc_str value; - * This function is needed because no one else knows what dc_str - * looks like. - */ -const char * -dc_str2charp DC_DECLARG((value)) - dc_str value DC_DECLEND -{ - return ((struct dc_string *)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 ((struct dc_string *)value)->s_len; -} - - -/* initialize the strings subsystem */ -void -dc_string_init DC_DECLVOID() -{ - /* nothing to do for this implementation */ -} diff --git a/gnu/usr.bin/dc/dc-version.h b/gnu/usr.bin/dc/dc-version.h deleted file mode 100644 index 917be944117f..000000000000 --- a/gnu/usr.bin/dc/dc-version.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * dc version number - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -#define Version "dc 1.0" diff --git a/gnu/usr.bin/dc/dc.1 b/gnu/usr.bin/dc/dc.1 deleted file mode 100644 index ce1eda16b3e4..000000000000 --- a/gnu/usr.bin/dc/dc.1 +++ /dev/null @@ -1,393 +0,0 @@ -.TH DC 1 "07 Apr 1994" "GNU Project" -.ds dc \fIdc\fP -.ds Dc \fIDc\fP -.SH NAME -dc \- an arbitrary precision calculator -.SH SYNOPSIS -dc -.SH -DESCRIPTION -.PP -\*(Dc is a reverse-polish desk calculator which supports -unlimited precision arithmetic. -It also allows you to define and call macros. -Normally \*(dc reads from the standard input; -if any command arguments are given to it, they are filenames, -and \*(dc reads and executes the contents of the files before reading -from standard input. -All normal output is to standard output; -all error output is to standard error. -.PP -A reverse-polish calculator stores numbers on a stack. -Entering a number pushes it on the stack. -Arithmetic operations pop arguments off the stack and push the results. -.PP -To enter a number in -.IR dc , -type the digits with an optional decimal point. -Exponential notation is not supported. -To enter a negative number, -begin the number with ``_''. -``-'' cannot be used for this, -as it is a binary operator for subtraction instead. -To enter two numbers in succession, -separate them with spaces or newlines. -These have no meaning as commands. -.PD -.SH -Printing Commands -.TP -.B p -Prints the value on the top of the stack, -without altering the stack. -A newline is printed after the value. -.TP -.B P -Prints the value on the top of the stack, popping it off, -and does not print a newline after. -.TP -.B f -Prints the entire contents of the stack -.ig -and the contents of all of the registers, -.. -without altering anything. -This is a good command to use if you are lost or want -to figure out what the effect of some command has been. -.PD -.SH -Arithmetic -.TP -.B + -Pops two values off the stack, adds them, -and pushes the result. -The precision of the result is determined only -by the values of the arguments, -and is enough to be exact. -.TP -.B - -Pops two values, -subtracts the first one popped from the second one popped, -and pushes the result. -.TP -.B * -Pops two values, multiplies them, and pushes the result. -The number of fraction digits in the result is controlled -by the current precision value (see below) and does not -depend on the values being multiplied. -.TP -.B / -Pops two values, -divides the second one popped from the first one popped, -and pushes the result. -The number of fraction digits is specified by the precision value. -.TP -.B % -Pops two values, -computes the remainder of the division that the -.B / -command would do, -and pushes that. -The division is done with as many fraction digits -as the precision value specifies, -and the remainder is also computed with that many fraction digits. -.TP -.B ^ -Pops two values and exponentiates, -using the first value popped as the exponent -and the second popped as the base. -The fraction part of the exponent is ignored. -The precision value specifies the number of fraction -digits in the result. -.TP -.B v -Pops one value, -computes its square root, -and pushes that. -The precision value specifies the number of fraction digits in the result. -.PP -Most arithmetic operations are affected by the ``precision value'', -which you can set with the -.B k -command. -The default precision value is zero, -which means that all arithmetic except for -addition and subtraction produces integer results. -.PP -The remainder operation -.B % -requires some explanation: -applied to arguments ``a'' and ``b'' it produces ``a - (b * (a / b))'', -where ``a / b'' is computed in the current precision. -.SH -Stack Control -.TP -.B c -Clears the stack, rendering it empty. -.TP -.B d -Duplicates the value on the top of the stack, -pushing another copy of it. -Thus, ``4d*p'' computes 4 squared and prints it. -.SH -Registers -.PP -\*(Dc provides 256 memory registers, -each named by a single character. -You can store a number or a string in a register and retrieve it later. -.TP -.BI s r -Pop the value off the top of the stack and store -it into register -.IR r . -.TP -.BI l r -Copy the value in register -.I r -and push it onto the stack. -This does not alter the contents of -.IR r . -.PP -Each register also contains its own stack. -The current register value is the top of the register's stack. -.TP -.BI S r -Pop the value off the top of the (main) stack and -push it onto the stack of register -.IR r . -The previous value of the register becomes inaccessible. -.TP -.BI L r -Pop the value off the top of register -.IR r 's -stack and push it onto the main stack. -The previous value -in register -.IR r 's -stack, if any, -is now accessible via the -.BI l r -command. -.ig -.PP -The -.B f -command prints a list of all registers that have contents stored in them, -together with their contents. -Only the current contents of each register -(the top of its stack) -is printed. -.. -.SH -Parameters -.PP -\*(Dc has three parameters that control its operation: -the precision, the input radix, and the output radix. -The precision specifies the number -of fraction digits to keep in the result of most arithmetic operations. -The input radix controls the interpretation of numbers typed in; -all numbers typed in use this radix. -The output radix is used for printing numbers. -.PP -The input and output radices are separate parameters; -you can make them unequal, -which can be useful or confusing. -The input radix must be between 2 and 36 inclusive. -The output radix must be at least 2. -The precision must be zero or greater. -The precision is always measured in decimal digits, -regardless of the current input or output radix. -.TP -.B i -Pops the value off the top of the stack -and uses it to set the input radix. -.TP -.B o -Pops the value off the top of the stack -and uses it to set the output radix. -.TP -.B k -Pops the value off the top of the stack -and uses it to set the precision. -.TP -.B I -Pushes the current input radix on the stack. -.TP -.B O -Pushes the current output radix on the stack. -.TP -.B K -Pushes the current precision on the stack. -.SH -Strings -.PP -\*(Dc can operate on strings as well as on numbers. -The only things you can do with strings are -print them and execute them as macros -(which means that the contents of the string are processed as -\*(dc commands). -All registers and the stack can hold strings, -and \*(dc always knows whether any given object is a string or a number. -Some commands such as arithmetic operations demand numbers -as arguments and print errors if given strings. -Other commands can accept either a number or a string; -for example, the -.B p -command can accept either and prints the object -according to its type. -.TP -.BI [ characters ] -Makes a string containing -.I characters -(contained between balanced -.B [ -and -.B ] -characters), -and pushes it on the stack. -For example, -.B [foo]P -prints the characters -.B foo -(with no newline). -.TP -.B x -Pops a value off the stack and executes it as a macro. -Normally it should be a string; -if it is a number, -it is simply pushed back onto the stack. -For example, -.B [1p]x -executes the macro -.B 1p -which pushes -.B 1 -on the stack and prints -.B 1 -on a separate line. -.PP -Macros are most often stored in registers; -.B [1p]sa -stores a macro to print -.B 1 -into register -.BR a , -and -.B lax -invokes this macro. -.TP -.BI > r -Pops two values off the stack and compares them -assuming they are numbers, -executing the contents of register -.I r -as a macro if the original top-of-stack -is greater. -Thus, -.B 1 2>a -will invoke register -.BR a 's -contents and -.B 2 1>a -will not. -.TP -.BI < r -Similar but invokes the macro if the original top-of-stack is less. -.TP -.BI = r -Similar but invokes the macro if the two numbers popped are equal. -.ig -This can also be validly used to compare two strings for equality. -.. -.TP -.B ? -Reads a line from the terminal and executes it. -This command allows a macro to request input from the user. -.TP -.B q -exits from a macro and also from the macro which invoked it. -If called from the top level, -or from a macro which was called directly from the top level, -the -.B q -command will cause \*(dc to exit. -.TP -.B Q -Pops a value off the stack and uses it as a count -of levels of macro execution to be exited. -Thus, -.B 3Q -exits three levels. -The -.B Q -command will never cause \*(dc to exit. -.SH -Status Inquiry -.TP -.B Z -Pops a value off the stack, -calculates the number of digits it has -(or number of characters, if it is a string) -and pushes that number. -.TP -.B X -Pops a value off the stack, -calculates the number of fraction digits it has, -and pushes that number. -For a string, -the value pushed is -.\" -1. -0. -.TP -.B z -Pushes the current stack depth; -the number of objects on the stack before the execution of the -.B z -command. -.SH -Miscellaneous -.TP -.B ! -Will run the rest of the line as a system command. -.TP -.B # -Will interpret the rest of the line as a comment. -.TP -.BI : r -Will pop the top two values off of the stack. -The old second-to-top value will be stored in the array -.IR r , -indexed by the old top-of-stack value. -.TP -.BI ; r -Pops the top-of-stack and uses it as an index into -the array -.IR r . -The selected value is then pushed onto the stack. -.SH -NOTES -.PP -The array operations -.B : -and -.B ; -are usually only used by traditional implementations of -.IR bc . -(The GNU -.I bc -is self contained and does not need \*(dc to run.) -The comment operator -.B # -is a new command not found in traditional implementations of -.IR dc . -.SH -BUGS -.PP -Email bug reports to -.BR bug-gnu-utils@prep.ai.mit.edu . -Be sure to include the word ``dc'' somewhere in the ``Subject:'' field. -.SH HISTORY -A -.I dc -command appeared in -Version 1 AT&T UNIX. diff --git a/gnu/usr.bin/dc/dc.h b/gnu/usr.bin/dc/dc.h deleted file mode 100644 index 7193aea89670..000000000000 --- a/gnu/usr.bin/dc/dc.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Header file for dc routines - * - * Copyright (C) 1994 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can either send email to this - * program's author (see below) or write to: The Free Software Foundation, - * Inc.; 675 Mass Ave. Cambridge, MA 02139, USA. - */ - -#ifndef DC_DEFS_H -#define DC_DEFS_H - -/* 'I' is a command, and bases 17 and 18 are quite - * unusual, so we limit ourselves to bases 2 to 16 - */ -#define DC_IBASE_MAX 16 - -#define DC_SUCCESS 0 -#define DC_DOMAIN_ERROR 1 -#define DC_FAIL 2 /* generic failure */ - - -#ifndef __STDC__ -# define DC_PROTO(x) () -# define DC_DECLVOID() () -# define DC_DECLARG(arglist) arglist -# define DC_DECLSEP ; -# define DC_DECLEND ; -#else /* __STDC__ */ -# define DC_PROTO(x) x -# define DC_DECLVOID() (void) -# define DC_DECLARG(arglist) ( -# define DC_DECLSEP , -# define DC_DECLEND ) -#endif /* __STDC__ */ - - -typedef enum {DC_FALSE, DC_TRUE} dc_boolean; - - -/* type discriminant for dc_data */ -typedef enum {DC_UNINITIALIZED, DC_NUMBER, DC_STRING} dc_value_type; - -/* generic pointer for information hiding */ -typedef void *Opaque; - -/* only dc-math.c knows what dc_num's *really* look like */ -typedef Opaque dc_num; - -/* only dc-string.c knows what dc_str's *really* look like */ -typedef Opaque 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/gnu/usr.bin/dc/doc/Makefile b/gnu/usr.bin/dc/doc/Makefile index 41a1d4a471bb..7dfcd6c1c0a3 100644 --- a/gnu/usr.bin/dc/doc/Makefile +++ b/gnu/usr.bin/dc/doc/Makefile @@ -1,5 +1,11 @@ +# Makefile copyright Andreas Klemm 1998 +# +# $Id: Makefile,v 1.4 1997/10/14 18:32:38 jraynard Exp $ + +.PATH: ${.CURDIR}/../../../../contrib/bc/doc + INFO = dc INFOSECTION= "System Utilities" -INFOENTRY_dc= "* DC: (dc). The GNU desk calculator." +INFOENTRY_dc= "* DC: (dc). The GNU Desktop Calculator." .include diff --git a/gnu/usr.bin/dc/doc/dc.texinfo b/gnu/usr.bin/dc/doc/dc.texinfo deleted file mode 100644 index 73f687be2f4d..000000000000 --- a/gnu/usr.bin/dc/doc/dc.texinfo +++ /dev/null @@ -1,425 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename dc.info -@settitle dc, an arbitrary precision calculator -@c %**end of header - -@c This file has the new style title page commands. -@c Run `makeinfo' rather than `texinfo-format-buffer'. - -@c smallbook - -@c tex -@c \overfullrule=0pt -@c end tex - -@c Combine indices. -@synindex cp fn -@syncodeindex vr fn -@syncodeindex ky fn -@syncodeindex pg fn -@syncodeindex tp fn - -@ifinfo -This file documents @sc{dc}, an arbitrary precision calculator. - -Published by the Free Software Foundation, -675 Massachusetts Avenue, -Cambridge, MA 02139 USA - -Copyright (C) 1984 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. -@end ifinfo - -@setchapternewpage off - -@titlepage -@title dc, an arbitrary precision calculator - -@author by Ken Pizzini -@author manual by Richard Stallman -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 1994 Free Software Foundation, Inc. - -@sp 2 -Published by the Free Software Foundation, @* -675 Massachusetts Avenue, @* -Cambridge, MA 02139 USA - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation approved -by the Foundation. - -@end titlepage -@page - -@node Top, Introduction, (dir), (dir) - -@menu -* Introduction:: Introduction -* Printing Commands:: Printing Commands -* Arithmetic:: Arithmetic -* Stack Control:: Stack Control -* Registers:: Registers -* Parameters:: Parameters -* Strings:: Strings -* Status Inquiry:: Status Inquiry -* Miscellaneous:: Other commands -* Notes:: Notes -@end menu - -@node Introduction, Printing Commands, Top, Top -@comment node-name, next, previous, up -@chapter Introduction - -@sc{dc} is a reverse-polish desk calculator -which supports unlimited precision arithmetic. -It also allows you to define and call macros. -Normally @sc{dc} reads from the standard input; -if any command arguments are given to it, they are filenames, -and @sc{dc} reads and executes the contents of the files -before reading from standard input. -All normal output is to standard output; -all error messages are written to standard error. - -To exit, use @samp{q}. -@kbd{C-c} does not exit; -it is used to abort macros that are looping, etc. -(Currently this is not true; @kbd{C-c} does exit.) - -A reverse-polish calculator stores numbers on a stack. -Entering a number pushes it on the stack. -Arithmetic operations pop arguments off the stack and push the results. - -To enter a number in @sc{dc}, type the digits, -with an optional decimal point. -Exponential notation is not supported. -To enter a negative number, begin the number with @samp{_}. -@samp{-} cannot be used for this, as it is a binary operator -for subtraction instead. -To enter two numbers in succession, -separate them with spaces or newlines. -These have no meaning as commands. - -@node Printing Commands, Arithmetic, Introduction, Top -@chapter Printing Commands - -@table @samp -@item p -Prints the value on the top of the stack, -without altering the stack. -A newline is printed after the value. - -@item P -Prints the value on the top of the stack, popping it off, -and does not print a newline after. - -@item f -Prints the entire contents of the stack -@c and the contents of all of the registers, -without altering anything. -This is a good command to use if you are lost or want -to figure out what the effect of some command has been. -@end table - -@node Arithmetic, Stack Control, Printing Commands, Top -@chapter Arithmetic - -@table @samp -@item + -Pops two values off the stack, adds them, and pushes the result. -The precision of the result is determined only -by the values of the arguments, and is enough to be exact. - -@item - -Pops two values, subtracts the first one popped -from the second one popped, and pushes the result. - -@item * -Pops two values, multiplies them, and pushes the result. -The number of fraction digits in the result is controlled -by the current precision value (see below) and does not -depend on the values being multiplied. - -@item / -Pops two values, divides the second one popped -from the first one popped, and pushes the result. -The number of fraction digits is specified by the precision value. - -@item % -Pops two values, -computes the remainder of the division that -the @samp{/} command would do, -and pushes that. -The division is done with as many fraction digits -as the precision value specifies, -and the remainder is also computed with that many fraction digits. - -@item ^ -Pops two values and exponentiates, -using the first value popped as the exponent -and the second popped as the base. -The fraction part of the exponent is ignored. -The precision value specifies the number of fraction -digits in the result. - -@item v -Pops one value, computes its square root, and pushes that. -The precision value specifies the number of fraction digits -in the result. -@end table - -Most arithmetic operations are affected by the @emph{precision value}, -which you can set with the @samp{k} command. -The default precision value is zero, -which means that all arithmetic except for -addition and subtraction produces integer results. - -The remainder operation (@samp{%}) requires some explanation: -applied to arguments @samp{a} and @samp{b} -it produces @samp{a - (b * (a / b))}, -where @samp{a / b} is computed in the current precision. - -@node Stack Control, Registers, Arithmetic, Top -@chapter Stack Control - -@table @samp -@item c -Clears the stack, rendering it empty. - -@item d -Duplicates the value on the top of the stack, -pushing another copy of it. -Thus, @samp{4d*p} computes 4 squared and prints it. -@end table - -@node Registers, Parameters, Stack Control, Top -@chapter Registers - -@sc{dc} provides 256 memory registers, each named by a single character. -You can store a number in a register and retrieve it later. - -@table @samp -@item s@var{r} -Pop the value off the top of the stack and -store it into register @var{r}. - -@item l@var{r} -Copy the value in register @var{r}, -and push it onto the stack. -This does not alter the contents of @var{r}. - -Each register also contains its own stack. -The current register value is the top of the register's stack. - -@item S@var{r} -Pop the value off the top of the (main) stack and -push it onto the stack of register @var{r}. -The previous value of the register becomes inaccessible. - -@item L@var{r} -Pop the value off the top of register @var{r}'s stack -and push it onto the main stack. -The previous value in register @var{r}'s stack, if any, -is now accessible via the @samp{l@var{r}} command. -@end table -@c -@c The @samp{f} command prints a list of all registers that have contents -@c stored in them, together with their contents. -@c Only the current contents of each register (the top of its stack) -@c is printed. - -@node Parameters, Strings, Registers, Top -@chapter Parameters - -@sc{dc} has three parameters that control its operation: -the precision, the input radix, and the output radix. -The precision specifies the number of fraction digits -to keep in the result of most arithmetic operations. -The input radix controls the interpretation of numbers typed in; -@emph{all} numbers typed in use this radix. -The output radix is used for printing numbers. - -The input and output radices are separate parameters; -you can make them unequal, which can be useful or confusing. -The input radix must be between 2 and 36 inclusive. -The output radix must be at least 2. -The precision must be zero or greater. -The precision is always measured in decimal digits, -regardless of the current input or output radix. - -@table @samp -@item i -Pops the value off the top of the stack -and uses it to set the input radix. - -@item o -Pops the value off the top of the stack -and uses it to set the output radix. - -@item k -Pops the value off the top of the stack -and uses it to set the precision. - -@item I -Pushes the current input radix on the stack. - -@item O -Pushes the current output radix on the stack. - -@item K -Pushes the current precision on the stack. - -@end table - -@node Strings, Status Inquiry, Parameters, Top -@chapter Strings - -@sc{dc} can operate on strings as well as on numbers. -The only things you can do with strings are print them -and execute them as macros -(which means that the contents of the string are processed as @sc{dc} commands). -Both registers and the stack can hold strings, -and @sc{dc} always knows whether any given object is a string or a number. -Some commands such as arithmetic operations demand numbers -as arguments and print errors if given strings. -Other commands can accept either a number or a string; -for example, the @samp{p} command can accept either and prints the object -according to its type. - -@table @samp -@item [@var{characters}] -Makes a string containing @var{characters} and pushes it on the stack. -For example, @samp{[foo]P} prints the characters @samp{foo} -(with no newline). - -@item x -Pops a value off the stack and executes it as a macro. -Normally it should be a string; -if it is a number, it is simply pushed back onto the stack. -For example, @samp{[1p]x} executes the macro @samp{1p}, -which pushes 1 on the stack and prints @samp{1} on a separate line. - -Macros are most often stored in registers; -@samp{[1p]sa} stores a macro to print @samp{1} into register @samp{a}, -and @samp{lax} invokes the macro. - -@item >@var{r} -Pops two values off the stack and compares them -assuming they are numbers, -executing the contents of register @var{r} as a macro -if the original top-of-stack is greater. -Thus, @samp{1 2>a} will invoke register @samp{a}'s contents -and @samp{2 1>a} will not. - -@item <@var{r} -Similar but invokes the macro if the original top-of-stack is less. - -@item =@var{r} -Similar but invokes the macro if the two numbers popped are equal. -@c This can also be validly used to compare two strings for equality. - -@item ? -Reads a line from the terminal and executes it. -This command allows a macro to request input from the user. - -@item q -During the execution of a macro, -this command exits from the macro and also from the macro which invoked it. -If called from the top level, -or from a macro which was called directly from the top level, -the @samp{q} command will cause @sc{dc} to exit. - -@item Q -Pops a value off the stack and uses it as a count -of levels of macro execution to be exited. -Thus, @samp{3Q} exits three levels. -@end table - -@node Status Inquiry, Miscellaneous, Strings, Top -@chapter Status Inquiry - -@table @samp -@item Z -Pops a value off the stack, -calculates the number of digits it has -(or number of characters, if it is a string) -and pushes that number. - -@item X -Pops a value off the stack, -calculates the number of fraction digits it has, -and pushes that number. -For a string, the value pushed is -@c -1. -0. - -@item z -Pushes the current stack depth; -the number of objects on the stack -before the execution of the @samp{z} command. -@end table - -@node Miscellaneous, Notes, Status Inquiry, Top -@chapter Miscellaneous - -@table @samp -@item ! -Will run the rest of the line as a system command. - -@item # -Will interpret the rest of the line as a comment. - -@item :@var{r} -Will pop the top two values off of the stack. -The old second-to-top value will be stored in the array @var{r}, -indexed by the old top-of-stack value. - -@item ;@var{r} -Pops the top-of-stack and uses it as an index into -the array @var{r}. -The selected value is then pushed onto the stack. -@end table - -@node Notes, , Miscellaneous, Top -@chapter Notes - -The array operations @samp{:} and @samp{;} are usually -only used by traditional implementations of BC. -(The GNU BC is self contained and does not need @sc{dc} to run.) -The comment operator @samp{#} is a new command -not found in traditional implementations of @sc{dc}. - -@contents -@bye