diff --git a/CHANGES b/CHANGES index 37787be..3b39c89 100644 --- a/CHANGES +++ b/CHANGES @@ -136,6 +136,9 @@ Following is the change from calc version 2.11.0t8 to date: an error while processing 'args' and drops into interactive mode without the terminal bindings being set. + Updated to some extend, the help/statement and help/command help + files with new information about SHOW, QUIT, EXIT and ABORT. + Fixed misc compiler warnings. diff --git a/calc.h b/calc.h index cf3b6e1..8a4617f 100644 --- a/calc.h +++ b/calc.h @@ -164,6 +164,7 @@ extern int d_flag; /* TRUE => disable heading, lib_debug == 0 */ extern int c_flag; /* TRUE => continue after error if permitted */ extern int i_flag; /* TRUE => try to go interactive after error */ extern int stoponerror; /* >0 => stop, <0 => continue, ==0 => use -c */ +extern BOOL abort_now; /* TRUE => try to go interactive */ extern char *pager; /* $PAGER or default */ extern int stdin_tty; /* TRUE if stdin is a tty */ diff --git a/codegen.c b/codegen.c index cb18ab6..4528bd8 100644 --- a/codegen.c +++ b/codegen.c @@ -86,6 +86,7 @@ getcommands(BOOL toplevel) /* firewall */ name[0] = '\0'; name[MAXCMD+1] = '\0'; + abort_now = FALSE; /* getcommands */ if (!toplevel) @@ -164,6 +165,13 @@ getcommands(BOOL toplevel) if (evaluate(FALSE)) updateoldvalue(curfunc); freefunc(curfunc); + 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); + } } } } @@ -874,7 +882,7 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d break; case T_SYMBOL: - if (nextchar() == ':') { /****HACK HACK ****/ + if (nextchar() == ':') { /****HACK HACK****/ definelabel(tokensymbol()); if (gettoken() == T_RIGHTBRACE) { rescantoken(); diff --git a/help/command b/help/command index 58f2020..0ac0d3e 100644 --- a/help/command +++ b/help/command @@ -14,12 +14,10 @@ Command sequence described in the next section. - NOTE: Calc commands are in lower case. UPPER case is used below - for emphasis only, and should be considered in lower case. - - - DEFINE function(params) { body } - DEFINE function(params) = expression + define a function + ----------------- + define function(params) { body } + define function(params) = expression This first form defines a full function which can consist of declarations followed by many statements which implement the function. @@ -30,13 +28,22 @@ Command sequence and question mark operators can be useful. Examples of simple functions are: - define sumcubes(a, b) = a^3 + b^3; - define pimod(a) = a % pi(); + define sumcubes(a, b) = a^3 + b^3 + define pimod(a) = a % pi() + define printnum(a, n, p) + { + if (p == 0) { + print a: "^": n, "=", a^n; + } else { + print a: "^": n, "mod", p, "=", pmod(a,n,p); + } + } - HELP - This displays a general help message. - READ filename + read calc commands + ------------------ + read filename + read -once filename This reads definitions from the specified filename. The name can be quoted if desired. The calculator uses the CALCPATH environment variable to search @@ -52,14 +59,11 @@ Command sequence evaluate or functions to define, just like at the top level command level. - If the -m mode disallows opening of files for reading, - this command will be disabled. + When -once is given, the read command acts like the regular + read expect that it will ignore filename if is has been + previously read. - READ -once filename - This command acts like the regular READ expect that it - will ignore filename if is has been previously read. - - This command is particularly useful in a library that + The read -once form is particularly useful in a library that needs to read a 2nd library. By using the READ -once command, one will not reread that 2nd library, nor will once risk entering into a infinite READ loop (where @@ -69,7 +73,10 @@ Command sequence If the -m mode disallows opening of files for reading, this command will be disabled. - WRITE filename + + write calc commands + ------------------- + write filename This writes the values of all global variables to the specified filename, in such a way that the file can be later read in order to recreate the variable values. @@ -81,23 +88,221 @@ Command sequence If the -m mode disallows opening of files for writing, this command will be disabled. - QUIT - This leaves the calculator, when given as a top-level - command. - ABORT - Forces an immediate quit regardless calc command line - flags and termina state. + quit or exit + ------------ + quit + quit string + exit + exit string + The action of these commands depends on where they are used. + At the interactive level, they will cause calc it edit. + This is the normal way to leave the calculator. In any + other use, they will stop the current calculation as if + an error had occurred. - CD - Change the current directory to the home directory, if $HOME + If a string is given, then the string is printed as the reason + for quitting, otherwise a general quit message is printed. + The routine name and line number which executed the quit is + also printed in either case. + + Exit is an alias for quit. + + Quit is useful when a routine detects invalid arguments, + in order to stop a calculation cleanly. For example, + for a square root routine, an error can be given if the + supplied parameter was a negative number, as in: + + define mysqrt(n) + { + if (! isnum(n)) + quit "non-numeric argument"; + if (n < 0) + quit "Negative argument"; + return sqrt(n); + } + + See 'more information about abort and quit' below for + more information. + + + + abort + ----- + abort + abort string + This command behaves like QUIT except that it will attempt + to return to the interactive level if permitted, otherwise + calc exit. + + See 'more information about abort and quit' below for + more information. + + + change current directory + ------------------------ + cd + cd dir + Change the current directory to 'dir'. If 'dir' is ommitted, + change the current directory to the home directory, if $HOME is set in the environment. - CD dir - Change the current directory to dir. + + show information + ---------------- + show item + This command displays some information where 'item' is + one of the following: + + blocks unfreed named blocks + builtin built in functions + config config parameters and values + constants cache of numeric constants + custom custom functions if calc -C was used + errors new error-values created + files open files, file position and sizes + function user-defined functions + globaltypes global variables + objfunctions possible object functions + objtypes defined objects + opcodes func internal opcodes for function `func' + sizes size in octets of calc value types + realglobals numeric global variables + statics unscoped static variables + numbers calc number cache + redcdata REDC data defined + strings calc string cache + literals calc literal cache + + Only the first 4 characters of item are examined, so: + + show globals + show global + show glob + + do the same thing. + + + calc help + --------- + help + help name + This displays a help related to 'name' or general + help of none is given. + + + =-= + + + more information about abort and quit + ===================================== + + Consider the following calc file called myfile.cal: + + print "start of myfile.cal"; + define q() {quit "quit from q()"; print "end of q()"} + define a() {abort "abort from a()"} + x = 3; + {print "start #1"; if (x > 1) q()} print "after #1"; + {print "start #2"; if (x > 1) a()} print "after #2"; + {print "start #3"; if (x > 1) quit "quit from 3rd statement"} + print "end of myfile.cal"; + + The command: + + calc read myfile + + will produce: + + q() defined + a() defined + start statment #1 + quit from q() + after statment #1 + start statment #2 + abort from a() + + The QUIT within the q() function prevented the ``end of q()'' + statement from being evaluated. This QUIT command caused + control to be returned to just after the place where q() + was called. + + Notice that unlike QUIT, the ABORT inside function a() halts + the processing of statements from the input source (myfile.cal). + Because calc was not interactive, ABORT causes calc to exit. + + The command: + + calc -i read myfile + + will produce: + + q() defined + a() defined + start statment #1 + quit from q() + after statment #1 + start statment #2 + abort from a() + > <==== calc interactive prompt + + because the '-i' calc causes ABORT to drop into an + interactive prompt. However typing a QUIT or ABORT + at the interactive prompt level will always calc to exit, + even when calc is invoked with '-i'. + + Also observe that both of these commands: + + cat myfile.cal | calc + cat myfile.cal | calc -i + + will produce: + + q() defined + a() defined + start statment #1 + quit from q() + after statment #1 + start statment #2 + abort from a() + + The ABORT inside function a() halts the processing of statements + from the input source (standard input). Because standard input + is not a terminal, using '-i' does not force it to drop into + an interactive prompt. + + If one were to type in the contents of myfile.cal interactively, + calc will produce: + + > print "start of myfile.cal"; + start of myfile.cal + > define q() {quit "quit from q()"; print "end of q()"} + q() defined + > define a() {abort "abort from a()"} + a() defined + > x = 3; + > {print "start #1"; if (x > 1) q()} print "after #1"; + start statment #1 + quit from q() + after statment #1 + > {print "start #2"; if (x > 1) a()} print "after #2"; + start statment #2 + abort from a() + > {print "start #3"; if (x > 1) quit "quit from 3rd statement"} + start #3 + quit from 3rd statement + + The ABORT from within the a() function returned control to + the interactive level. + + The QUIT (after the if (x > 1) ...) will cause calc to exit + because it was given at the interactive prompt level. + + + =-= Also see the help topic: statement flow control and declaration statements - usage for -m modes + usage how to invoke the calc command and calc -options diff --git a/help/statement b/help/statement index d34a36c..ad64f90 100644 --- a/help/statement +++ b/help/statement @@ -10,28 +10,38 @@ Statements expressions are optional and may be omitted (as in RETURN). - NOTE: Calc commands are in lower case. UPPER case is used below - for emphasis only, and should be considered in lower case. - - - IF (expr) statement - IF (expr) statement ELSE statement - FOR (optionalexpr ; optionalexpr ; optionalexpr) statement - WHILE (expr) statement - DO statement WHILE (expr) - CONTINUE - BREAK - GOTO label + C-like statements + ----------------- + { statement } + { statement; ... statement } + if (expr) statement + if (expr) statement ELSE statement + for (optionalexpr ; optionalexpr ; optionalexpr) statement + while (expr) statement + do statement while (expr) + continue + break + goto label These all work like in normal C. - RETURN optionalexpr + See 'help expression' for details on expressions. + See 'help builtin' for details on calc builtin functions. + + + return + ------ + return optionalexpr + return ( optionalexpr ) This returns a value from a function. Functions always have a return value, even if this statement is not used. If no return statement is executed, or if no expression is specified in the return statement, then the return value from the function is the null type. - SWITCH (expr) { caseclauses } + + switch + ------ + switch (expr) { caseclauses } Switch statements work similarly to C, except for the following. A switch can be done on any type of value, and the case statements can be of any type of values. @@ -42,17 +52,12 @@ Statements is the exception, and only matches once all other cases have been tested. - { statements } - This is a normal list of statements, each one ended by - a semicolon. Unlike the C language, no declarations are - permitted within an inner-level compound statement. - Declarations are only permitted at the beginning of a - function definition, or at the beginning of an expression - sequence. - MAT variable [dimension] [dimension] ... - MAT variable [dimension, dimension, ...] - MAT variable [] = { value, ... } + matrix + ------ + mat variable [dimension] [dimension] ... + mat variable [dimension, dimension, ...] + mat variable [] = { value, ... } This creates a matrix variable with the specified dimensions. Matrices can have from 1 to 4 dimensions. When specifying multiple dimensions, you can use either the standard C syntax, @@ -119,8 +124,11 @@ Statements local mat temp[5]; static mat strtable[] = {"hi", "there", "folks"); - OBJ type { elementnames } optionalvariables - OBJ type variable + + object + ------ + obj type { elementnames } optionalvariables + obj type variable These create a new object type, or create one or more variables of the specified type. For this calculator, an object is just a structure which is implicitly acted @@ -183,36 +191,12 @@ Statements static obj point temp2 = {4, 3}; global obj point p1, p2, p3; - EXIT string - QUIT string - This command is used in two cases. At the top command - line level, quit will exit from the calculator. This - is the normal way to leave the calculator. In any other - use, quit will abort the current calculation as if an - error had occurred. If a string is given, then the string - is printed as the reason for quitting, otherwise a general - quit message is printed. The routine name and line number - which executed the quit is also printed in either case. - Quit is useful when a routine detects invalid arguments, - in order to stop a calculation cleanly. For example, - for a square root routine, an error can be given if the - supplied parameter was a negative number, as in: - - define mysqrt(n) - { - if (n < 0) - quit "Negative argument"; - ... - } - - Exit is an alias for quit. - - ABORT - Forces an immediate quit regardless calc command line - flags and termina state. - - PRINT exprs + print expressions + ----------------- + print expr + print expr, ... expr + print expr: ... expr For interactive expression evaluation, the values of all typed-in expressions are automatically displayed to the user. However, within a function or loop, the printing of @@ -231,8 +215,8 @@ Statements expression unless the statement ends with a colon. As examples: - print 3, 4; prints "3 4" and newline. - print 5:; prints "5" with no newline. + print 3, 4; prints "3 4" and newline. + print 5:; prints "5" with no newline. print 'a' : 'b' , 'c'; prints "ab c" and newline. print; prints a newline. @@ -250,25 +234,9 @@ Statements prints the name of the file that was opened. - SHOW item - This command displays some information. - - builtin built in functions - global global variables - function user-defined functions - objfunc possible object functions - config config parameters and values - objtype defined objects - - Only the first 4 characters of item are examined, so: - - show globals - show global - show glob - - do the same thing. - - Also see the help topic: command top level commands + expression calc expression syntax + builtin calc builtin functions + usage how to invoke the calc command and calc -options diff --git a/lib/regress.cal b/lib/regress.cal index c3bd2c5..fa028f8 100644 --- a/lib/regress.cal +++ b/lib/regress.cal @@ -3302,7 +3302,7 @@ define test_fileops() print '4261: Ending test_fileops'; } -print '071: parsed test_redc()'; +print '071: parsed test_fileops()'; /* diff --git a/lib_calc.c b/lib_calc.c index d637b9c..9dc4c7c 100644 --- a/lib_calc.c +++ b/lib_calc.c @@ -99,6 +99,7 @@ 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 */ +BOOL abort_now = FALSE; /* TRUE => go interactive now, if permitted */ int no_env = FALSE; /* TRUE (-e) => ignore env vars on startup */ int errmax = ERRMAX; /* if >= 0, maximum value for errcount */ diff --git a/opcodes.c b/opcodes.c index d293fe1..c14173b 100644 --- a/opcodes.c +++ b/opcodes.c @@ -33,7 +33,6 @@ 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 @@ -3714,11 +3713,12 @@ calculate(FUNC *fp, int argcount) freevalue(stack--); funcname = oldname; funcline = oldline; - if (abort_now) { + if (abort_now && stack == stackarray) { if (!stdin_tty) run_state = RUN_EXIT; else if (run_state < RUN_PRE_TOP_LEVEL) run_state = RUN_PRE_TOP_LEVEL; + freefunc(curfunc); longjmp(jmpbuf, 1); } return; diff --git a/sample/many_random.c b/sample/many_random.c index cae1769..4ba29d6 100644 --- a/sample/many_random.c +++ b/sample/many_random.c @@ -33,18 +33,6 @@ */ -#if defined(__sgi) -# include "../longbits.h" -# if defined(HAVE_B64) -typedef USB64 k_sigset_t; -# else -typedef struct { - USB32 sigbits[2]; -} k_sigset_t; -# endif -#endif - - #include #include #include "../calc.h" diff --git a/sample/test_random.c b/sample/test_random.c index c1ecb31..8a5ffd7 100644 --- a/sample/test_random.c +++ b/sample/test_random.c @@ -33,18 +33,6 @@ */ -#if defined(__sgi) -# include "../longbits.h" -# if defined(HAVE_B64) -typedef USB64 k_sigset_t; -# else -typedef struct { - USB32 sigbits[2]; -} k_sigset_t; -# endif -#endif - - #include #include #include "../calc.h" diff --git a/version.c b/version.c index 806b085..cc72586 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.7" /* test number or empty string if no patch */ +#define MINOR_PATCH "8.8" /* test number or empty string if no patch */ /* * calc version constants