diff --git a/BUGS b/BUGS index e3468e2..d21febe 100644 --- a/BUGS +++ b/BUGS @@ -68,17 +68,6 @@ importantly, fixes (in the form of a context diff patch) to: Known bugs: - * calc -i ignores quit binding or EOF input in some cases. For example: - - echo 'define f(x) { ' > myfile - calc -i read myfile - "./myfile", line 2: End-of-file in function body - Error in commands - > - - At this point, calc will re-prompt if you give it an EOF, or - type ^D while using lib/altbind or while ^D is bound to quit. - * When compiled on some Big Endian machines with BASEB forced to be 16 (by setting LONGLONG_BITS= 0 in the Makefile), calc fails a number of regression tests: diff --git a/CHANGES b/CHANGES index 62bdf3c..37787be 100644 --- a/CHANGES +++ b/CHANGES @@ -132,6 +132,10 @@ Following is the change from calc version 2.11.0t8 to date: Fixed the help/custom_cal, help/new_custom, and help/copy files so that they contain the correct contents instead of the 'usage' file. + Fixed problem with loss of bindings when .calc -i args runs into + an error while processing 'args' and drops into interactive mode + without the terminal bindings being set. + Fixed misc compiler warnings. diff --git a/codegen.c b/codegen.c index c91e00f..cb18ab6 100644 --- a/codegen.c +++ b/codegen.c @@ -862,6 +862,17 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d } break; + case T_ABORT: + switch (gettoken()) { + case T_STRING: + addopone(OP_ABORT, tokenstring()); + break; + default: + addopone(OP_ABORT, -1); + rescantoken(); + } + break; + case T_SYMBOL: if (nextchar() == ':') { /****HACK HACK ****/ definelabel(tokensymbol()); diff --git a/help/command b/help/command index 2ed9655..58f2020 100644 --- a/help/command +++ b/help/command @@ -85,6 +85,10 @@ Command sequence This leaves the calculator, when given as a top-level command. + ABORT + Forces an immediate quit regardless calc command line + flags and termina state. + CD Change the current directory to the home directory, if $HOME is set in the environment. diff --git a/help/statement b/help/statement index 1bfd7a2..d34a36c 100644 --- a/help/statement +++ b/help/statement @@ -208,6 +208,9 @@ Statements Exit is an alias for quit. + ABORT + Forces an immediate quit regardless calc command line + flags and termina state. PRINT exprs For interactive expression evaluation, the values of all diff --git a/hist.c b/hist.c index 3dbc7f4..b23e9f7 100644 --- a/hist.c +++ b/hist.c @@ -242,7 +242,7 @@ int hist_getline(char *prompt, char *buf, int len) { if (!inited) - (void) hist_init((char *) NULL); + (void) hist_init(calcbindings); HS.prompt = prompt; HS.bufsize = len - 2; diff --git a/lib_calc.c b/lib_calc.c index 2d7a27d..d637b9c 100644 --- a/lib_calc.c +++ b/lib_calc.c @@ -89,19 +89,19 @@ int i_flag = FALSE; /* TRUE => go interactive if permitted */ /* * global values */ -char *calcpath; /* $CALCPATH or default */ -char *calcrc; /* $CALCRC or default */ -char *calcbindings; /* $CALCBINDINGS or default */ -char *home; /* $HOME or default */ -char *pager; /* $PAGER or default */ -char *shell; /* $SHELL or default */ -int stdin_tty = FALSE; /* TRUE if stdin is a tty */ +char *calcpath = NULL; /* $CALCPATH or default */ +char *calcrc = NULL; /* $CALCRC or default */ +char *calcbindings = NULL; /* $CALCBINDINGS or default */ +char *home = NULL; /* $HOME or default */ +char *pager = NULL; /* $PAGER or default */ +char *shell = NULL; /* $SHELL or default */ +int stdin_tty = FALSE; /* TRUE if stdin is a tty */ int havecommands = FALSE; /* TRUE if have one or more cmd args */ int stoponerror = FALSE; /* >0 => stop, <0 => continue on error */ -int post_init = FALSE; /* TRUE setjmp for math_error is ready */ +int post_init = FALSE; /* TRUE setjmp for math_error is ready */ -int no_env = FALSE; /* TRUE (-e) => ignore env vars on startup */ -int errmax = ERRMAX; /* if >= 0, maximum value for errcount */ +int no_env = FALSE; /* TRUE (-e) => ignore env vars on startup */ +int errmax = ERRMAX; /* if >= 0, maximum value for errcount */ NUMBER *epsilon_default; /* default allowed error for float calcs */ diff --git a/opcodes.c b/opcodes.c index d66331b..d293fe1 100644 --- a/opcodes.c +++ b/opcodes.c @@ -33,6 +33,7 @@ static BOOL saveval = TRUE; /* to enable or disable saving */ static int calc_errno; /* most recent error-number */ static int errcount; /* counts calls to error_value */ static BOOL go; +static BOOL abort_now; /* * global symbols @@ -3139,13 +3140,21 @@ o_quit(FUNC *fp, long index) if (cp) printf("%s\n", cp); else - printf("Quit statement executed\n"); + printf("Quit or abort executed\n"); if (!inputisterminal() && fp->f_name[0] == '*') closeinput(); go = FALSE; } +static void +o_abort(FUNC *fp, long index) +{ + abort_now = TRUE; + o_quit(fp, index); +} + + static void o_getepsilon(void) { @@ -3533,7 +3542,8 @@ static struct opcode opcodes[MAX_OPCODE+1] = { {o_backslash, OPNUL, "BACKSLASH"}, /* unary backslash op */ {o_setminus, OPNUL, "SETMINUS"}, /* binary backslash op */ {o_plus, OPNUL, "PLUS"}, /* unary + op */ - {o_jumpnn, OPJMP, "JUMPNN"} /* jump if non-null */ + {o_jumpnn, OPJMP, "JUMPNN"}, /* jump if non-null */ + {o_abort, OPONE, "ABORT"} /* abort operation */ }; @@ -3567,6 +3577,7 @@ calculate(FUNC *fp, int argcount) funcname = fp->f_name; funcline = 0; go = TRUE; + abort_now = FALSE; origargcount = argcount; while (argcount < fp->f_paramcount) { stack++; @@ -3703,6 +3714,13 @@ calculate(FUNC *fp, int argcount) freevalue(stack--); funcname = oldname; funcline = oldline; + if (abort_now) { + if (!stdin_tty) + run_state = RUN_EXIT; + else if (run_state < RUN_PRE_TOP_LEVEL) + run_state = RUN_PRE_TOP_LEVEL; + longjmp(jmpbuf, 1); + } return; } @@ -3748,8 +3766,10 @@ dumpop(unsigned long *pc) case OP_PRINTSTRING: case OP_STRING: printf(" \"%s\"\n", findstring((long)(*pc))->s_str); return 2; - case OP_QUIT: - printf(" \"%s\"\n", findstring((long)(*pc))->s_str); + case OP_QUIT: case OP_ABORT: + if ((long)(*pc) >= 0) + printf(" \"%s\"", findstring((long)(*pc))->s_str); + putchar('\n'); return 2; case OP_INDEXADDR: printf(" %ld %ld\n", pc[0], pc[1]); diff --git a/opcodes.h b/opcodes.h index ddafcb9..883a9f3 100644 --- a/opcodes.h +++ b/opcodes.h @@ -144,7 +144,8 @@ #define OP_SETMINUS 129L /* binary backslash */ #define OP_PLUS 130L /* unary + */ #define OP_JUMPNN 131L /* jump if top value is non-null */ -#define MAX_OPCODE 131L /* highest legal opcode */ +#define OP_ABORT 132L /* abort operation */ +#define MAX_OPCODE 132L /* highest legal opcode */ /* diff --git a/token.c b/token.c index ce4faa7..0c73fd6 100644 --- a/token.c +++ b/token.c @@ -83,6 +83,7 @@ static struct keyword keywords[] = { {"print", T_PRINT}, {"cd", T_CD}, {"undefine", T_UNDEFINE}, + {"abort", T_ABORT}, {NULL, 0} }; diff --git a/token.h b/token.h index 845a389..32d69dd 100644 --- a/token.h +++ b/token.h @@ -110,6 +110,7 @@ #define T_PRINT 124 /* print keyword */ #define T_CD 125 /* change directory keyword */ #define T_UNDEFINE 126 /* undefine keyword */ +#define T_ABORT 127 /* abort operation */ #define iskeyword(n) ((n) > 100) /* TRUE if token is a keyword */ diff --git a/version.c b/version.c index eee784a..806b085 100644 --- a/version.c +++ b/version.c @@ -12,7 +12,7 @@ #define MAJOR_VER 2 /* major version */ #define MINOR_VER 11 /* minor version */ #define MAJOR_PATCH 0 /* patch level or 0 if no patch */ -#define MINOR_PATCH "8.6" /* test number or empty string if no patch */ +#define MINOR_PATCH "8.7" /* test number or empty string if no patch */ /* * calc version constants