Release calc version 2.11.1t1

This commit is contained in:
Landon Curt Noll
1999-12-15 01:35:49 -08:00
parent f3913609ea
commit 6f5e8bf1b6
519 changed files with 17771 additions and 4208 deletions

237
calc.c
View File

@@ -1,11 +1,35 @@
/*
* Copyright (c) 1997 David I. Bell
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
* calc - arbitrary precision calculator
*
* Arbitrary precision calculator.
* Copyright (C) 1999 David I. Bell, Landon Curt Noll and Ernest Bowen
*
* Primary author: David I. Bell
*
* Calc is open software; you can redistribute it and/or modify it under
* the terms of the version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* Calc is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* A copy of version 2.1 of the GNU Lesser General Public License is
* distributed with calc under the filename COPYING-LGPL. You should have
* received a copy with calc; if not, write to Free Software Foundation, Inc.
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* @(#) $Revision: 29.1 $
* @(#) $Id: calc.c,v 29.1 1999/12/14 09:15:34 chongo Exp $
* @(#) $Source: /usr/local/src/cmd/calc/RCS/calc.c,v $
*
* Under source code control: 1990/02/15 01:48:11
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://reality.sgi.com/chongo/tech/comp/calc/
*/
#include <stdio.h>
#include <signal.h>
#include <pwd.h>
@@ -46,7 +70,7 @@
* static definitions and functions
*/
static void intint(int arg); /* interrupt routine */
static void script_args(int *argc, char ***argv, char **shellfile);
static int script_args(int argc,char ***argv,char **shellfile,char **program);
/*
@@ -57,7 +81,7 @@ main(int argc, char **argv)
{
int want_defhelp = 0; /* 1=> we only want the default help */
int cmdlen; /* length of the command string */
char *shellfile = NULL; /* =!NULL ==> name of calc shell script */
char *shellfile = NULL; /* != NULL ==> name of calc shell script */
extern char *optarg; /* option argument */
extern int optind; /* option index */
int c; /* option */
@@ -68,10 +92,12 @@ main(int argc, char **argv)
* parse args
*/
program = argv[0];
/* catch the case of a leading -s option */
if (argc > 2 && strncmp(argv[1], "-s", 2) == 0) {
/* catch the case of a leading -S option */
if (argc > 2 && strncmp(argv[1], "-S", 2) == 0) {
/* convert the calc shell options into command line options */
script_args(&argc, &argv, &shellfile);
argc = script_args(argc, &argv, &shellfile, &program);
/* -S implies -s */
s_flag = TRUE;
}
/* process command line options */
while ((c = getopt(argc, argv, "Cehim:npquvcdD:s")) != -1) {
@@ -144,15 +170,15 @@ main(int argc, char **argv)
* parse the -D optarg
*
* Could be calc_debug
* or calc_debug:lib_debug
* or calc_debug:lib_debug:user_debug
* or calc_debug:resource_debug
* or calc_debug:resource_debug:user_debug
*/
calc_debug = optarg;
p = strchr(optarg, ':');
if (p != NULL) {
*p = '\0';
lib_debug = p+1;
p = strchr(lib_debug, ':');
resource_debug = p+1;
p = strchr(resource_debug, ':');
if (p != NULL) {
*p = '\0';
user_debug = p+1;
@@ -160,14 +186,10 @@ main(int argc, char **argv)
}
break;
case 's':
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
fprintf(stderr,
"%s: -s may only be used in a calc shell script\n",
program);
exit(1);
s_flag = TRUE;
break;
case 'S':
/*FALLTHRU*/
default:
/*
* we are too early in processing to call
@@ -175,47 +197,69 @@ main(int argc, char **argv)
*/
fprintf(stderr,
"usage: %s [-c] [-C] [-d] [-e] [-h] [-i] [-m mode]\n"
"\t[-D calc_debug[:lib_debug:[user_debug]]]\n"
"\t[-n] [-p] [-q] [-u] [-v] [[--] calc_cmd ...]\n",
"\t[-D calc_debug[:resource_debug:[user_debug]]]\n"
"\t[-n] [-p] [-q] [-s] [-u] [-v] "
"[[--] calc_cmd ...]\n",
program);
exit(1);
}
}
havecommands = (optind < argc);
/*
* If -S was given via a calc shell script, imply -p and -d
* unless -i was also given.
*/
if (shellfile != NULL && !i_flag) {
p_flag = TRUE;
d_flag = TRUE;
}
/*
* look at the length of any trailing command args
*
* We make room for the trailing '\0\n' as well as an extra guard byte.
*/
for (cmdlen=0, i=optind; i < argc; ++i) {
/* argument + space separator */
cmdlen += strlen(argv[i]) + 1;
}
if (i > MAXCMD) {
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
fprintf(stderr,
"%s: command in arg list is too long\n", program);
exit(1);
}
/*
* We will form a command the remaining args separated by spaces.
*
* However, if -S is in effect, we will pretend that we have no
* command args and allow the argv() builtin access to the strings.
*/
cmdbuf[0] = '\0';
if (optind < argc) {
strcpy(cmdbuf, argv[optind]);
cmdlen = strlen(argv[optind]);
for (i=optind+1; i < argc; ++i) {
cmdbuf[cmdlen++] = ' ';
strcpy(cmdbuf+cmdlen, argv[i]);
cmdlen += strlen(argv[i]);
if (s_flag) {
havecommands = FALSE;
argc_value = argc - optind;
argv_value = argv + optind;
} else {
havecommands = (optind < argc);
for (cmdlen=0, i=optind; i < argc; ++i) {
/* argument + space separator */
cmdlen += strlen(argv[i]) + 1;
}
cmdbuf[cmdlen++] = '\n';
cmdbuf[cmdlen] = '\0';
if (i > MAXCMD) {
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
fprintf(stderr,
"%s: command in arg list is too long\n",
program);
exit(1);
}
/*
* Form a command the remaining args separated by spaces.
*/
if (optind < argc) {
strcpy(cmdbuf, argv[optind]);
cmdlen = strlen(argv[optind]);
for (i=optind+1; i < argc; ++i) {
cmdbuf[cmdlen++] = ' ';
strcpy(cmdbuf+cmdlen, argv[i]);
cmdlen += strlen(argv[i]);
}
cmdbuf[cmdlen++] = '\n';
cmdbuf[cmdlen] = '\0';
}
argc_value = 0;
argv_value = argv+argc;
}
/*
@@ -232,7 +276,7 @@ main(int argc, char **argv)
libcalc_call_me_first();
stdin_tty = isatty(0); /* assume stdin is on fd 0 */
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: stdin_tty is %d\n", stdin_tty);
printf("main: stdin_tty is %d\n", stdin_tty);
if (want_defhelp) {
givehelp(DEFAULTCALCHELP);
libcalc_call_me_last();
@@ -245,6 +289,8 @@ main(int argc, char **argv)
if (!havecommands && stdin_tty) {
if (!d_flag) {
printf("%s (version %s)\n", CALC_TITLE, version());
printf("Calc is open software. For license details "
"type: help copyright\n");
printf("[%s]\n\n",
"Type \"exit\" to exit, or \"help\" for help.");
}
@@ -288,14 +334,14 @@ main(int argc, char **argv)
if (run_state == RUN_BEGIN) {
if (!q_flag && allow_read) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_RCFILES));
run_state = RUN_RCFILES;
runrcfiles();
}
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_PRE_CMD_ARGS));
run_state = RUN_PRE_CMD_ARGS;
@@ -309,7 +355,7 @@ main(int argc, char **argv)
closeinput();
runrcfiles();
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_PRE_CMD_ARGS));
run_state = RUN_PRE_CMD_ARGS;
@@ -319,13 +365,13 @@ main(int argc, char **argv)
} else {
if ((havecommands && !i_flag) || !stdin_tty) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_EXIT_WITH_ERROR));
run_state = RUN_EXIT_WITH_ERROR;
} else {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_PRE_CMD_ARGS));
run_state = RUN_PRE_CMD_ARGS;
@@ -333,21 +379,27 @@ main(int argc, char **argv)
}
}
/* XXX - if shellfile != NULL process shellfile here */
if (run_state == RUN_PRE_CMD_ARGS) {
if (havecommands) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_CMD_ARGS));
run_state = RUN_CMD_ARGS;
(void) openstring(cmdbuf, (long) strlen(cmdbuf));
getcommands(FALSE);
closeinput();
} else if (shellfile != NULL) {
/* XXX - shellfile stuff needs it own run_state name */
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_CMD_ARGS));
run_state = RUN_CMD_ARGS;
getshellfile(shellfile);
}
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_PRE_TOP_LEVEL));
run_state = RUN_PRE_TOP_LEVEL;
@@ -359,7 +411,7 @@ main(int argc, char **argv)
getcommands(FALSE);
if (inputlevel() == 0)
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_PRE_TOP_LEVEL));
run_state = RUN_PRE_TOP_LEVEL;
@@ -368,13 +420,13 @@ main(int argc, char **argv)
closeinput();
if (!stdin_tty || !i_flag || p_flag) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_EXIT_WITH_ERROR));
run_state = RUN_EXIT_WITH_ERROR;
} else {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_PRE_TOP_LEVEL));
run_state = RUN_PRE_TOP_LEVEL;
@@ -383,9 +435,10 @@ main(int argc, char **argv)
}
if (run_state == RUN_PRE_TOP_LEVEL) {
if (stdin_tty && ((havecommands && !i_flag) || p_flag)) {
if (stdin_tty &&
(((havecommands || shellfile) && !i_flag) || p_flag)) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_EXIT));
run_state = RUN_EXIT;
@@ -397,7 +450,7 @@ main(int argc, char **argv)
openterminal();
}
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_TOP_LEVEL));
run_state = RUN_TOP_LEVEL;
@@ -416,7 +469,7 @@ main(int argc, char **argv)
getcommands(TRUE);
} else {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
printf("main: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_EXIT_WITH_ERROR));
run_state = RUN_EXIT_WITH_ERROR;
@@ -492,9 +545,9 @@ math_error(char *fmt, ...)
* script_args - concert shell script options into command line form
*
* When a calc shell script is executed, the args are presented to calc
* in a different form. Consider the a calc shell script called /tmp/calcit:
* in a different form. Consider the a calc shell script called /tmp/calcit:
*
* #!/usr/local/bin/calc -s -q -p
* #!/usr/local/bin/calc -S -q -p
* a=eval(prompt("Enter a: "));
* b=eval(prompt("Enter b: "));
* print a+b;
@@ -507,20 +560,20 @@ math_error(char *fmt, ...)
*
* argc: 5
* argv[0]: "/usr/local/bin/calc"
* argv[1]: "-s -q -p -e"
* argv[1]: "-S -q -p -e"
* argv[2]: "/tmp/calcit"
* argv[3]: "-D"
* argv[4]: "31"
* argv[5]: NULL
*
* NOTE: The user MUST put -s as the first characters on the calc shell
* NOTE: The user MUST put -S as the first characters on the calc shell
* script #! line, right after the calc binary path.
*
* NOTE: The arg supplied on the #! calc shell script line are returned
* as a single string. All tabs are converted into spaces.
*
* We must remember the calc script filename, break apart the #! args
* and remove the -s argument. In the above case we would return:
* and remove the -S argument. In the above case we would return:
*
* argc: 6
* argv[0]: "/usr/local/bin/calc"
@@ -532,12 +585,12 @@ math_error(char *fmt, ...)
* argv[6]: NULL
*
* shellfile: "/tmp/calcit"
* s_flag: TRUE
*/
static void
script_args(int *argc_p, char ***argv_p, char **shellfile_p)
static int
script_args(int argc, char ***argv_p, char **shellfile_p, char **program_p)
{
int argc; /* argc to return */
char **argv; /* argv to return */
char **argv; /* new argv to return */
char *shellfile; /* shell file pathname to return */
int delta; /* the change needed in argc */
int i;
@@ -546,11 +599,10 @@ script_args(int *argc_p, char ***argv_p, char **shellfile_p)
char *q;
/*
* must have at least 3 args and the 2nd must start with -s
* must have at least 3 args and the 2nd must start with -S
*/
argc = *argc_p;
argv = *argv_p;
if (argc < 3 || strncmp(argv[1], "-s", 2) != 0) {
if (argc < 3 || strncmp(argv[1], "-S", 2) != 0) {
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
@@ -562,18 +614,18 @@ script_args(int *argc_p, char ***argv_p, char **shellfile_p)
shellfile = argv[2];
/*
* count the additional args beyond the -s
* count the additional args beyond the -S
*/
if (argv[1][2] == ' ') {
/*
* process args beyond -s on the #!/usr/local/bin line
* process args beyond -S on the #!/usr/local/bin line
*/
p = argv[1]+3 + strspn(argv[1]+3," ");
q = p;
if (q == '\0') {
/* only trailing spaces after -s, ignore them */
/* only trailing spaces after -S, ignore them */
for (i = 3; i <= argc; ++i) {
argv[i-2] = argv[i];
}
@@ -581,7 +633,7 @@ script_args(int *argc_p, char ***argv_p, char **shellfile_p)
} else {
/* count the space separated strings that follow -s */
/* count the space separated strings that follow -S */
for (delta = -1; p != NULL && *p;
p = strchr(p+1,' '), ++delta) {
/* skip multiple spaces in a row */
@@ -597,7 +649,7 @@ script_args(int *argc_p, char ***argv_p, char **shellfile_p)
*/
fprintf(stderr,
"%s: failed to malloc %d pointers\n",
program, argc+delta);
shellfile, argc+delta);
exit(1);
}
@@ -613,7 +665,7 @@ script_args(int *argc_p, char ***argv_p, char **shellfile_p)
*/
fprintf(stderr,
"%s: failed to duplicate 1st arg\n",
program);
shellfile);
exit(1);
}
@@ -634,7 +686,7 @@ script_args(int *argc_p, char ***argv_p, char **shellfile_p)
}
/*
* catch the case of #!/usr/local/bin -stuff_not_extra_args
* catch the case of #!/usr/local/bin -Stuff_not_extra_args
*/
} else if (argv[1][2] != '\0') {
@@ -643,13 +695,13 @@ script_args(int *argc_p, char ***argv_p, char **shellfile_p)
* libcalc_call_me_last() - nothing to cleanup
*/
fprintf(stderr,
"%s: malformed #! line, -s must be "
"%s: malformed #! line, -S must be "
"followed by space or newline\n",
program);
shellfile);
exit(1);
/*
* Only -s was given in the #!/usr/local/bin line, so we just
* Only -S was given in the #!/usr/local/bin line, so we just
* toss the 2nd and 3rd args
*/
} else {
@@ -660,10 +712,11 @@ script_args(int *argc_p, char ***argv_p, char **shellfile_p)
}
/*
* return and set the argc, argv, shellfile_p values
* return and set the argc, argv, shellfile_p and s_flag values
*/
*argc_p = argc;
*argv_p = argv;
*shellfile_p = shellfile;
return;
*program_p = shellfile;
s_flag = TRUE;
return argc;
}