Compare commits

...

3 Commits

Author SHA1 Message Date
Landon Curt Noll
df32e3956d Release calc version 2.11.0t9.3.1 2017-05-21 15:38:32 -07:00
Landon Curt Noll
75e742c716 Release calc version 2.11.0t9.2 2017-05-21 15:38:32 -07:00
Landon Curt Noll
1b42111665 Release calc version 2.11.0t9.1.1 2017-05-21 15:38:32 -07:00
30 changed files with 643 additions and 176 deletions

39
BUGS
View File

@@ -96,6 +96,45 @@ Known bugs:
the terminal in a 'bad' state, as if stty -icanon -echo -echoe the terminal in a 'bad' state, as if stty -icanon -echo -echoe
had been executed. had been executed.
* Dec Alpha Linux compiling with gcc-2.95.1 (or gcc-2.95.2) and
-O2 fails the version 2.11.0t8.10 regression test with:
make -s check
000: Beginning regression tests
001: Some of these tests may take a while ...
002: Within each section, output should be numbered sequentially
003: parsed global definitions
004: parsed vrfy()
005: parsed prob(str)
006: parsed getglobalvar()
007: parsed test_booleans()
008: parsed test_variables()
make: *** [check] Segmentation fault (core dumped)
Other programs have reported problems when compiling -O2 with
gcc-2.95.1 on the Alpha and Mips.
One work-a-round is to not compile with -O2 (perhaps just -O).
Another work-a-round is not use gcc-2.95.1.
* On a Digital UNIX V4.0F (Rev. 1229) on a 500 Mhz 21264, make check
dies a horrible death starting in test 600 and 622 gives 100s of
messages for calc version 2.11.0t9.2 using the Dec's cc with -O2
and without -std0:
600: Beginning test_bignums
601: muldivcheck 1
**** abc != acb: 602: muldivcheck 2
**** acb != bac: 602: muldivcheck 2
...
**** t4 != a4: 622: algcheck 1
**** t5 != a5: 622: algcheck 1
**** t6 != a6: 622: algcheck 1
**** t4 != a4: 622: algcheck 1
...
it finally hangs at test 2000.
We are sure some more bugs exist. When you find them, please let We are sure some more bugs exist. When you find them, please let
us know! See the above for details on how to report and were to us know! See the above for details on how to report and were to
EMail your bug reports and hopefully patches to fix them. EMail your bug reports and hopefully patches to fix them.

66
CHANGES
View File

@@ -28,11 +28,10 @@ Following is the change from calc version 2.11.0t8.9.1 to date:
The eval(str) builtin will return an error-value rather than cause The eval(str) builtin will return an error-value rather than cause
an execution error str has a scan-error. an execution error str has a scan-error.
Declaration are permitted to end with EOF as well as a newline or ';'. Declarations are permitted to end with EOF as well as a newline or ';'.
When prompt() occurs in reading a file, it will take inout from When prompt() occurs while reading a file, it will take input from
the terminal rather than taking it from a file. For example, the terminal rather than taking it from a file. For example:
this script, when read, now works:
/* This demonstrates the use of prompt() and some other things */ /* This demonstrates the use of prompt() and some other things */
config("verbose_quit", 0); config("verbose_quit", 0);
@@ -52,17 +51,70 @@ Following is the change from calc version 2.11.0t8.9.1 to date:
} }
print "Good bye"; print "Good bye";
Comments entered at inputisterminal level may be spread over several Comments entered at input terminal level may be spread over several
lines. For example: lines. For example:
/* /*
* These commands work given the file: comment.cal * Assume that this calc script is called: comment.cal
* * Then these commands now work:
* cat comment.cal | calc * cat comment.cal | calc
* calc < comment.cal * calc < comment.cal
*/ */
print "Hello"; print "Hello";
Added:
-D calc_debug[:lib_debug:[user_debug]]
to set the initial value of config("calc_debug"), config("lib_debug")
and config("user_debug").
The : separated strings of -D are interpreted as signed 32 bit values.
After an optional leading sign a leading zero indicates octal
conversion, and a leading ``0x'' or ``0X'' hexadecimal conversion.
Otherwise, decimal conversion is assumed.
Reordered the config structure moving calc_debug ahead of lib_debug.
Added bits 4 and 5 to config("calc_debug"):
4 Report on changes to the state of stdin as well as changes
to internal variables that control the setting and restoring
of stdin.
5 Report on changes to the run state of calc.
Fixed portability issue in seed.c relating to /dev/urandom and ustat.
Added a fix from Martin Buck <mb@netwings.ch> to detect when
calc aborts early instead of completing the regression test.
Now 'make chk' will require the last line of calc output to
end in the string ``Ending regression tests''.
Added a patch from Martin Buck <mb@netwings.ch> to allow use of
GNU-readline. Note that GNU-readline is not shipped with calc.
His patch only provides the hooks to use it. One must comment out:
USE_READLINE=
READLINE_LIB=
READLINE_INCLUDE=
and comment in:
USE_READLINE= -DUSE_READLINE
READLINE_LIB= -lreadline -lhistory
READLINE_INCLUDE= -I/usr/include/readline
in addition to pre-installing GNU-readline in your system to use
this facility.
Changed the "object already defined" math_error message to a
scanerror message.
Removed the limit on the number of object types.
Calc tarballs are now named calc-version.tar.gz and untar into
a sub-directory called calc-version.
Following is the change from calc version 2.11.0t8 to 2.11.0t8.9: Following is the change from calc version 2.11.0t8 to 2.11.0t8.9:

View File

@@ -414,9 +414,37 @@ CALCRC= ${LIBDIR}/startup:~/.calcrc
# ${LIBDIR}/bindings uses ^D for editing # ${LIBDIR}/bindings uses ^D for editing
# ${LIBDIR}/altbind uses ^D for EOF # ${LIBDIR}/altbind uses ^D for EOF
# #
# NOTE: This facility is disabled if USE_READLINE is set to -DUSE_READLINE.
#
CALCBINDINGS= bindings CALCBINDINGS= bindings
#CALCBINDINGS= altbind #CALCBINDINGS= altbind
# Determine of the GNU-readline facility will be used instead of the
# built-in CALCBINDINGS above.
#
# USE_READLINE= Do not use GNU-readline, use CALCBINDINGS
# USE_READLINE= -DUSE_READLINE Use GNU-readline, do not use CALCBINDINGS
#
# NOTE: If you select the 'USE_READLINE= -DUSE_READLINE' mode, you must set:
#
# READLINE_LIB The flags needed to link in the readline
# and history libs
# READLINE_INCLUDE Where the readline include files reside
#
# NOTE: The GNU-readline code is not shipped with calc. You must have
# the appropriate headers and libs installed on your system in
# order to use it.
#
# If in doubt, set USE_READLINE, READLINE_LIB and READLINE_INCLUDE to nothing.
#
USE_READLINE=
READLINE_LIB=
READLINE_INCLUDE=
#
#USE_READLINE= -DUSE_READLINE
#READLINE_LIB= -lreadline -lhistory
#READLINE_INCLUDE= -I/usr/include/readline
# If $PAGER is not set, use this program to display a help file # If $PAGER is not set, use this program to display a help file
# #
CALCPAGER= more CALCPAGER= more
@@ -913,7 +941,7 @@ UTIL_OBJS= endian.o longbits.o have_newstr.o have_uid_t.o \
have_const.o fposval.o have_fpos.o longlong.o try_strarg.o \ have_const.o fposval.o have_fpos.o longlong.o try_strarg.o \
have_stdvs.o have_varvs.o have_posscl.o have_memmv.o calc_errno.o \ have_stdvs.o have_varvs.o have_posscl.o have_memmv.o calc_errno.o \
have_ustat.o have_getsid.o have_getpgid.o \ have_ustat.o have_getsid.o have_getpgid.o \
have_gettime.o have_getprid.o have_gettime.o have_getprid.o ver_calc.o
# these temp files may be created (and removed) during the build of BUILD_C_SRC # these temp files may be created (and removed) during the build of BUILD_C_SRC
# #
@@ -926,7 +954,7 @@ UTIL_TMP= ll_tmp fpos_tmp fposv_tmp const_tmp uid_tmp newstr_tmp vs_tmp \
UTIL_PROGS= align32 fposval have_uid_t longlong have_const \ UTIL_PROGS= align32 fposval have_uid_t longlong have_const \
endian longbits have_newstr have_stdvs have_varvs calc_errno \ endian longbits have_newstr have_stdvs have_varvs calc_errno \
have_ustat have_getsid have_getpgid \ have_ustat have_getsid have_getpgid \
have_gettime have_getprid have_gettime have_getprid ver_calc
# These files are required by the regress.cal regression test. # These files are required by the regress.cal regression test.
# #
@@ -984,7 +1012,7 @@ SAMPLE_PASSDOWN= Q="${Q}" \
LCFLAGS="${LCFLAGS}" \ LCFLAGS="${LCFLAGS}" \
LDFLAGS="${LDFLAGS}" \ LDFLAGS="${LDFLAGS}" \
ILDFLAGS="${ILDFLAGS}" \ ILDFLAGS="${ILDFLAGS}" \
CALC_LIBS="../libcalc.a ../custom/libcustcalc.a" \ CALC_LIBS="../libcalc.a ../custom/libcustcalc.a ${READLINE_LIB}" \
LCC="${LCC}" \ LCC="${LCC}" \
CC="${CC}" \ CC="${CC}" \
MAKE_FILE=${MAKE_FILE} \ MAKE_FILE=${MAKE_FILE} \
@@ -1032,7 +1060,7 @@ TARGETS= ${CALC_LIBS} custom/.all calc sample/sample \
all: .hsrc ${TARGETS} all: .hsrc ${TARGETS}
calc: .hsrc ${CALC_LIBS} ${CALCOBJS} calc: .hsrc ${CALC_LIBS} ${CALCOBJS}
${CC} ${LDFLAGS} ${CALCOBJS} ${CALC_LIBS} ${LD_DEBUG} -o calc ${CC} ${LDFLAGS} ${CALCOBJS} ${CALC_LIBS} ${LD_DEBUG} ${READLINE_LIB} -o calc
libcalc.a: ${LIBOBJS} ${MAKE_FILE} libcalc.a: ${LIBOBJS} ${MAKE_FILE}
-rm -f libcalc.a -rm -f libcalc.a
@@ -1059,7 +1087,7 @@ custom.o: custom.c ${MAKE_FILE}
${CC} ${CFLAGS} ${ALLOW_CUSTOM} -c custom.c ${CC} ${CFLAGS} ${ALLOW_CUSTOM} -c custom.c
hist.o: hist.c ${MAKE_FILE} hist.o: hist.c ${MAKE_FILE}
${CC} ${CFLAGS} ${TERMCONTROL} -c hist.c ${CC} ${CFLAGS} ${TERMCONTROL} ${USE_READLINE} ${READLINE_INCLUDE} -c hist.c
func.o: func.c ${MAKE_FILE} func.o: func.c ${MAKE_FILE}
${CC} ${CFLAGS} ${ALLOW_CUSTOM} -c func.c ${CC} ${CFLAGS} ${ALLOW_CUSTOM} -c func.c
@@ -2505,6 +2533,12 @@ h_list:
echo $$i; \ echo $$i; \
done done
# print the calc version
#
ver_calc: version.c
-rm -f $@
${LCC} ${ICFLAGS} -DCALC_VER ${ILDFLAGS} version.c -o $@
## ##
# #
# File distribution list generation. You can ignore this section. # File distribution list generation. You can ignore this section.
@@ -2516,34 +2550,27 @@ h_list:
distlist: ${DISTLIST} distlist: ${DISTLIST}
${Q}(for i in ${DISTLIST}; do \ ${Q}(for i in ${DISTLIST}; do \
echo calc/$$i; \ echo $$i; \
done; \ done; \
(cd help; ${MAKE} distlist \ (cd help; ${MAKE} distlist \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \ MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} SORT=${SORT}); \ HELPDIR=${HELPDIR} SORT=${SORT}); \
(cd lib; ${MAKE} distlist \ (cd lib; ${MAKE} distlist \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \ MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} SORT=${SORT}) ) | ${SORT}; \ HELPDIR=${HELPDIR} SORT=${SORT}); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} distlist); \ (cd custom; ${MAKE} ${CUSTOM_PASSDOWN} distlist); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} distlist) | ${SORT} (cd sample; ${MAKE} ${SAMPLE_PASSDOWN} distlist)) | ${SORT}
# The bsdi distribution has generated files as well as distributed files. distdir:
# The the .h files are placed under calc/gen_h. ${Q}(echo .; \
# (cd help; ${MAKE} distdir \
bsdilist: ${DISTLIST} ${BUILD_H_SRC} calc.1
${Q}(for i in ${DISTLIST}; do \
echo calc/$$i; \
done; \
for i in ${BUILD_H_SRC}; do \
echo calc/gen_h/$$i; \
done; \
echo calc/calc.1; \
(cd help; ${MAKE} bsdilist \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \ MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} SORT=${SORT}); \ HELPDIR=${HELPDIR} SORT=${SORT}); \
(cd lib; ${MAKE} bsdilist \ (cd lib; ${MAKE} distdir \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \ MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} SORT=${SORT}) ) | ${SORT} HELPDIR=${HELPDIR} SORT=${SORT}); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} distdir); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} distdir)) | ${SORT}
## ##
# #

88
calc.c
View File

@@ -40,6 +40,7 @@
* static definitions and functions * static definitions and functions
*/ */
static char *usage = "usage: %s [-c] [-C] [-d] [-e] [-h] [-i] [-m mode]\n" static char *usage = "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[-n] [-p] [-q] [-u] [-v] [[--] calc_cmd ...]\n";
static void intint(int arg); /* interrupt routine */ static void intint(int arg); /* interrupt routine */
@@ -55,13 +56,14 @@ main(int argc, char **argv)
extern char *optarg; /* option argument */ extern char *optarg; /* option argument */
extern int optind; /* option index */ extern int optind; /* option index */
int c; /* option */ int c; /* option */
char *p;
long i; long i;
/* /*
* parse args * parse args
*/ */
program = argv[0]; program = argv[0];
while ((c = getopt(argc, argv, "Cehim:npquvcd")) != -1) { while ((c = getopt(argc, argv, "Cehim:npquvcdD:")) != -1) {
switch (c) { switch (c) {
case 'C': case 'C':
#if defined(CUSTOM) #if defined(CUSTOM)
@@ -126,6 +128,26 @@ main(int argc, char **argv)
*/ */
printf("%s (version %s)\n", CALC_TITLE, version()); printf("%s (version %s)\n", CALC_TITLE, version());
exit(0); exit(0);
case 'D':
/*
* parse the -D optarg
*
* Could be calc_debug
* or calc_debug:lib_debug
* or calc_debug:lib_debug:user_debug
*/
calc_debug = optarg;
p = strchr(optarg, ':');
if (p != NULL) {
*p = '\0';
lib_debug = p+1;
p = strchr(lib_debug, ':');
if (p != NULL) {
*p = '\0';
user_debug = p+1;
}
}
break;
default: default:
/* /*
* we are too early in processing to call * we are too early in processing to call
@@ -185,6 +207,8 @@ main(int argc, char **argv)
*/ */
libcalc_call_me_first(); libcalc_call_me_first();
stdin_tty = isatty(0); /* assume stdin is on fd 0 */ 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);
if (want_defhelp) { if (want_defhelp) {
givehelp(DEFAULTCALCHELP); givehelp(DEFAULTCALCHELP);
libcalc_call_me_last(); libcalc_call_me_last();
@@ -239,9 +263,17 @@ main(int argc, char **argv)
*/ */
if (run_state == RUN_BEGIN) { if (run_state == RUN_BEGIN) {
if (!q_flag && allow_read) { if (!q_flag && allow_read) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_RCFILES));
run_state = RUN_RCFILES; run_state = RUN_RCFILES;
runrcfiles(); runrcfiles();
} }
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: 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; run_state = RUN_PRE_CMD_ARGS;
} }
@@ -252,25 +284,46 @@ main(int argc, char **argv)
if (inputlevel() == 0) { if (inputlevel() == 0) {
closeinput(); closeinput();
runrcfiles(); runrcfiles();
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: 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; run_state = RUN_PRE_CMD_ARGS;
} else { } else {
closeinput(); closeinput();
} }
} else { } else {
if ((havecommands && !i_flag) || !stdin_tty) if ((havecommands && !i_flag) || !stdin_tty) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: 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; run_state = RUN_EXIT_WITH_ERROR;
else } else {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: 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; run_state = RUN_PRE_CMD_ARGS;
} }
} }
}
if (run_state == RUN_PRE_CMD_ARGS) { if (run_state == RUN_PRE_CMD_ARGS) {
if (havecommands) { if (havecommands) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_CMD_ARGS));
run_state = RUN_CMD_ARGS; run_state = RUN_CMD_ARGS;
(void) openstring(cmdbuf, (long) strlen(cmdbuf)); (void) openstring(cmdbuf, (long) strlen(cmdbuf));
getcommands(FALSE); getcommands(FALSE);
closeinput(); closeinput();
} }
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: 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; run_state = RUN_PRE_TOP_LEVEL;
} }
@@ -279,19 +332,36 @@ main(int argc, char **argv)
if ((c_flag && !stoponerror) || stoponerror < 0) { if ((c_flag && !stoponerror) || stoponerror < 0) {
getcommands(FALSE); getcommands(FALSE);
if (inputlevel() == 0) if (inputlevel() == 0)
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: 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; run_state = RUN_PRE_TOP_LEVEL;
closeinput(); closeinput();
} else { } else {
closeinput(); closeinput();
if (!stdin_tty || !i_flag || p_flag) if (!stdin_tty || !i_flag || p_flag) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: 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; run_state = RUN_EXIT_WITH_ERROR;
else } else {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: 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; run_state = RUN_PRE_TOP_LEVEL;
} }
} }
}
if (run_state == RUN_PRE_TOP_LEVEL) { if (run_state == RUN_PRE_TOP_LEVEL) {
if (stdin_tty && ((havecommands && !i_flag) || p_flag)) { if (stdin_tty && ((havecommands && !i_flag) || p_flag)) {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_EXIT));
run_state = RUN_EXIT; run_state = RUN_EXIT;
} else { } else {
if (stdin_tty) { if (stdin_tty) {
@@ -300,6 +370,10 @@ main(int argc, char **argv)
resetinput(); resetinput();
openterminal(); openterminal();
} }
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_TOP_LEVEL));
run_state = RUN_TOP_LEVEL; run_state = RUN_TOP_LEVEL;
getcommands(TRUE); getcommands(TRUE);
} }
@@ -315,6 +389,10 @@ main(int argc, char **argv)
reinitialize(); reinitialize();
getcommands(TRUE); getcommands(TRUE);
} else { } else {
if (conf->calc_debug & CALCDBG_RUNSTATE)
printf("DEBUG: 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; run_state = RUN_EXIT_WITH_ERROR;
} }
} }

2
calc.h
View File

@@ -38,7 +38,6 @@
#define SYMBOLSIZE 256 /* maximum symbol name size */ #define SYMBOLSIZE 256 /* maximum symbol name size */
#define MAXINDICES 20 /* maximum number of indices for objects */ #define MAXINDICES 20 /* maximum number of indices for objects */
#define MAXLABELS 100 /* maximum number of user labels in function */ #define MAXLABELS 100 /* maximum number of user labels in function */
#define MAXOBJECTS 128 /* maximum number of object types */
#define MAXSTRING 1024 /* maximum size of string constant */ #define MAXSTRING 1024 /* maximum size of string constant */
#define MAXSTACK 1000 /* maximum depth of evaluation stack */ #define MAXSTACK 1000 /* maximum depth of evaluation stack */
#define MAXFILES 20 /* maximum number of opened files */ #define MAXFILES 20 /* maximum number of opened files */
@@ -208,6 +207,7 @@ typedef enum {
RUN_EXIT_WITH_ERROR = 7 /* exit with error */ RUN_EXIT_WITH_ERROR = 7 /* exit with error */
} run; } run;
extern run run_state; extern run run_state;
extern char *run_state_name(run state);
/* /*
* calc version information * calc version information

View File

@@ -15,17 +15,19 @@ calc \- arbitrary precision calculator
.RB [ \-c ] .RB [ \-c ]
.RB [ \-C ] .RB [ \-C ]
.RB [ \-d ] .RB [ \-d ]
.RB [ -D\ \&calc_debug[:lib_debug:[user_debug]] ]
.br
.in +5n
.RB [ \-e ] .RB [ \-e ]
.RB [ \-h ] .RB [ \-h ]
.RB [ \-i ] .RB [ \-i ]
.RB [ \-m\ \&mode ] .RB [ \-m\ \&mode ]
.br
.in +5n
.RB [ \-n ] .RB [ \-n ]
.RB [ \-p ] .RB [ \-p ]
.RB [ \-q ] .RB [ \-q ]
.RB [ \-u ] .RB [ \-u ]
.RB [ \-v ] .RB [ \-v ]
.br
.RB [ calc_cmd\ \&.\|.\|. ] .RB [ calc_cmd\ \&.\|.\|. ]
.in -5n .in -5n
.SH DESCRIPTION .SH DESCRIPTION
@@ -122,6 +124,34 @@ It's nearly ten past six.
This flag disables the reporting of missing calc This flag disables the reporting of missing calc
startup scripts ($CALCRC). startup scripts ($CALCRC).
.TP
.BR -D " calc_debug[:lib_debug:[user_debug]]"
Force the initial value of config("calc_debug"),
config("lib_debug") and config("user_debug").
.sp 1
The : separated strings are interpreted as signed 32 bit values.
After an optional leading sign a leading zero indicates octal
conversion, and a leading ``0x'' or ``0X'' hexadecimal
conversion. Otherwise, decimal conversion is assumed.
.sp 1
By default,
.I calc_debug
is 0,
.I lib_debug
is 3 and
.I lib_debug
is 0.
.sp 1
For more information use the following
.B calc
command:
.sp 1
.in +5n
.nf
help config
.fi
.in -5n
.TP .TP
.B \-e .B \-e
Ignore any environment variables on startup. Ignore any environment variables on startup.
@@ -182,7 +212,8 @@ This flag sets the permission mode of
It controls the ability for It controls the ability for
.B calc .B calc
to open files and execute programs. to open files and execute programs.
Mode may be a number from 0 to 7. .I Mode
may be a number from 0 to 7.
.sp 1 .sp 1
The mode value is interpreted in a way similar to that The mode value is interpreted in a way similar to that
of the of the
@@ -205,8 +236,8 @@ octal mode:
If one wished to run If one wished to run
.B calc .B calc
from a privileged user, one might want to use from a privileged user, one might want to use
.B \-m .BR \-m " 0"
0 in an effort to make in an effort to make
.B calc .B calc
somewhat more secure. somewhat more secure.
.sp 1 .sp 1
@@ -214,8 +245,8 @@ Mode bits for reading and writing apply only on an
open. open.
Files already open are not effected. Files already open are not effected.
Thus if one wanted to use the Thus if one wanted to use the
.B \-m .BR \-m " 0"
0 in an effort to make in an effort to make
.B calc .B calc
somewhat more secure, but still wanted to read and write a specific somewhat more secure, but still wanted to read and write a specific
file, one might want to do in file, one might want to do in
@@ -528,6 +559,9 @@ by this environment variable.
.sp .sp
Default value: ${CALCBINDINGS} Default value: ${CALCBINDINGS}
.sp .sp
This variable is not used if calc was compiled with GNU-readline support.
In that case, the standard readline mechanisms (see readline(3)) are used.
.sp
.SH CREDIT .SH CREDIT
\& \&
.br .br

View File

@@ -11,6 +11,7 @@ BEGIN {
havebuf2=0; havebuf2=0;
buf2=0; buf2=0;
error = 0; error = 0;
end_seen = 0;
} }
NF == 0 { NF == 0 {
@@ -29,6 +30,10 @@ NF == 0 {
next; next;
} }
/: Ending regression tests$/ {
end_seen = 1;
}
$1 ~ /^[0-9]+:/ { $1 ~ /^[0-9]+:/ {
if (error > 0) { if (error > 0) {
if (havebuf2) { if (havebuf2) {
@@ -71,7 +76,7 @@ END {
if (error > 0 && havebuf0) { if (error > 0 && havebuf0) {
print buf0; print buf0;
} }
if (error > 0) { if (error > 0 || !end_seen) {
exit(1); exit(1);
} else { } else {
exit(0); exit(0);

View File

@@ -382,7 +382,7 @@ getbody(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *defaul
return; return;
case T_EOF: case T_EOF:
scanerror(T_SEMICOLON, "End-of-file in function body"); scanerror(T_NULL, "End-of-file in function body");
return; return;
default: default:
@@ -995,7 +995,11 @@ getobjdeclaration(int symtype)
/*FALLTHRU*/ /*FALLTHRU*/
case T_RIGHTBRACE: case T_RIGHTBRACE:
(void) tokenmode(oldmode); (void) tokenmode(oldmode);
(void) defineobject(name, indices, count); if (defineobject(name, indices, count)) {
scanerror(T_NULL,
"Object type \"%s\" is already defined", name);
return;
}
getobjvars(name, symtype); getobjvars(name, symtype);
return; return;
case T_NEWLINE: case T_NEWLINE:
@@ -1350,7 +1354,7 @@ getopassignment(void)
return type; return type;
} }
if (isrvalue(type)) { if (isrvalue(type)) {
scanerror(T_NULL, "Illegal assignment in getopassignment"); scanerror(T_NULL, "Illegal assignment");
(void) getopassignment(); (void) getopassignment();
return (EXPR_RVALUE | EXPR_ASSIGN); return (EXPR_RVALUE | EXPR_ASSIGN);
} }
@@ -1443,7 +1447,7 @@ getassignment (void)
return type; return type;
} }
if (isrvalue(type)) { if (isrvalue(type)) {
scanerror(T_SEMICOLON, "Illegal assignment in getassignment"); scanerror(T_SEMICOLON, "Illegal assignment");
(void) getassignment(); (void) getassignment();
return (EXPR_RVALUE | EXPR_ASSIGN); return (EXPR_RVALUE | EXPR_ASSIGN);
} }

View File

@@ -94,8 +94,8 @@ CONFIG oldstd = { /* backward compatible standard configuration */
FALSE, /* skip duplicate block output lines */ FALSE, /* skip duplicate block output lines */
BLK_BASE_HEX, /* block octet print base */ BLK_BASE_HEX, /* block octet print base */
BLK_FMT_HD_STYLE, /* block output format */ BLK_FMT_HD_STYLE, /* block output format */
3, /* calc library debug level */
0, /* internal calc debug level */ 0, /* internal calc debug level */
3, /* calc library debug level */
0, /* user defined debug level */ 0, /* user defined debug level */
TRUE /* print Quit or abort executed messages */ TRUE /* print Quit or abort executed messages */
}; };
@@ -130,8 +130,8 @@ CONFIG newstd = { /* new non-backward compatible configuration */
FALSE, /* skip duplicate block output lines */ FALSE, /* skip duplicate block output lines */
BLK_BASE_HEX, /* block octet print base */ BLK_BASE_HEX, /* block octet print base */
BLK_FMT_HD_STYLE, /* block output format */ BLK_FMT_HD_STYLE, /* block output format */
3, /* calc library debug level */
0, /* internal calc debug level */ 0, /* internal calc debug level */
3, /* calc library debug level */
0, /* user defined debug level */ 0, /* user defined debug level */
TRUE /* print Quit or abort executed messages */ TRUE /* print Quit or abort executed messages */
}; };
@@ -809,20 +809,6 @@ setconfig(int type, VALUE *vp)
conf->blkfmt = temp; conf->blkfmt = temp;
break; break;
case CONFIG_LIB_DEBUG:
if (vp->v_type != V_NUM) {
math_error("Non numeric for lib_debug");
/*NOTREACHED*/
}
q = vp->v_num;
temp = qtoi(q);
if (qisfrac(q) || !zistiny(q->num)) {
math_error("Illegal lib_debug parameter value");
/*NOTREACHED*/
}
conf->lib_debug = temp;
break;
case CONFIG_CALC_DEBUG: case CONFIG_CALC_DEBUG:
if (vp->v_type != V_NUM) { if (vp->v_type != V_NUM) {
math_error("Non numeric for calc_debug"); math_error("Non numeric for calc_debug");
@@ -837,6 +823,20 @@ setconfig(int type, VALUE *vp)
conf->calc_debug = temp; conf->calc_debug = temp;
break; break;
case CONFIG_LIB_DEBUG:
if (vp->v_type != V_NUM) {
math_error("Non numeric for lib_debug");
/*NOTREACHED*/
}
q = vp->v_num;
temp = qtoi(q);
if (qisfrac(q) || !zistiny(q->num)) {
math_error("Illegal lib_debug parameter value");
/*NOTREACHED*/
}
conf->lib_debug = temp;
break;
case CONFIG_USER_DEBUG: case CONFIG_USER_DEBUG:
if (vp->v_type != V_NUM) { if (vp->v_type != V_NUM) {
math_error("Non numeric for user_debug"); math_error("Non numeric for user_debug");
@@ -1125,14 +1125,14 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
i = cfg->blkfmt; i = cfg->blkfmt;
break; break;
case CONFIG_LIB_DEBUG:
i = cfg->lib_debug;
break;
case CONFIG_CALC_DEBUG: case CONFIG_CALC_DEBUG:
i = cfg->calc_debug; i = cfg->calc_debug;
break; break;
case CONFIG_LIB_DEBUG:
i = cfg->lib_debug;
break;
case CONFIG_USER_DEBUG: case CONFIG_USER_DEBUG:
i = cfg->user_debug; i = cfg->user_debug;
break; break;
@@ -1214,8 +1214,8 @@ config_cmp(CONFIG *cfg1, CONFIG *cfg2)
cfg1->blkverbose != cfg2->blkverbose || cfg1->blkverbose != cfg2->blkverbose ||
cfg1->blkbase != cfg2->blkbase || cfg1->blkbase != cfg2->blkbase ||
cfg1->blkfmt != cfg2->blkfmt || cfg1->blkfmt != cfg2->blkfmt ||
cfg1->lib_debug != cfg2->lib_debug ||
cfg1->calc_debug != cfg2->calc_debug || cfg1->calc_debug != cfg2->calc_debug ||
cfg1->lib_debug != cfg2->lib_debug ||
cfg1->user_debug != cfg2->user_debug || cfg1->user_debug != cfg2->user_debug ||
cfg1->verbose_quit != cfg2->verbose_quit; cfg1->verbose_quit != cfg2->verbose_quit;
} }

View File

@@ -135,9 +135,9 @@ struct config {
BOOL blkverbose; /* TRUE => print all lines if a block */ BOOL blkverbose; /* TRUE => print all lines if a block */
int blkbase; /* block output base */ int blkbase; /* block output base */
int blkfmt; /* block output style */ int blkfmt; /* block output style */
int lib_debug; /* library debug, see LIB_DEBUG_XXX below */ long calc_debug; /* internal debug, see CALC_DEBUG_XXX below */
int calc_debug; /* internal debug, see CALC_DEBUG_XXX below */ long lib_debug; /* library debug, see LIB_DEBUG_XXX below */
int user_debug; /* user defined debug value: 0 default */ long user_debug; /* user defined debug value: 0 default */
BOOL verbose_quit; /* TRUE => print Quit or abort executed msg */ BOOL verbose_quit; /* TRUE => print Quit or abort executed msg */
}; };
typedef struct config CONFIG; typedef struct config CONFIG;
@@ -158,7 +158,9 @@ typedef struct config CONFIG;
#define CALCDBG_FUNC_QUIT (0x00000002) /* active functions when quit */ #define CALCDBG_FUNC_QUIT (0x00000002) /* active functions when quit */
#define CALCDBG_HASH_STATE (0x00000004) /* hash state details */ #define CALCDBG_HASH_STATE (0x00000004) /* hash state details */
#define CALCDBG_BLOCK (0x00000008) /* block debug */ #define CALCDBG_BLOCK (0x00000008) /* block debug */
#define CALCDBG_MASK (0x0000000f) #define CALCDBG_TTY (0x00000010) /* report TTY state changes */
#define CALCDBG_RUNSTATE (0x00000020) /* report run_state changes */
#define CALCDBG_MASK (0x0000003f)
/* /*
@@ -167,6 +169,9 @@ typedef struct config CONFIG;
extern CONFIG *conf; /* current configuration */ extern CONFIG *conf; /* current configuration */
extern CONFIG oldstd; /* backward compatible standard configuration */ extern CONFIG oldstd; /* backward compatible standard configuration */
extern CONFIG newstd; /* new non-backward compatible configuration */ extern CONFIG newstd; /* new non-backward compatible configuration */
extern char *calc_debug; /* !=NULL => value of config("calc_debug") */
extern char *lib_debug; /* !=NULL => value of config("lib_debug") */
extern char *user_debug; /* !=NULL => value of config("user_debug") */
/* /*

View File

@@ -337,15 +337,11 @@ libcustcalc.a: ${CUSTCALC_OBJ} ${MAKE_FILE} ../Makefile
distlist: ${DISTLIST} distlist: ${DISTLIST}
${Q}for i in ${DISTLIST}; do \ ${Q}for i in ${DISTLIST}; do \
echo calc/custom/$$i; \ echo custom/$$i; \
done done
# The bsdi distribution has generated files as well as distributed files. distdir:
# ${Q}echo custom
bsdilist: ${DISTLIST}
${Q}for i in ${DISTLIST}; do \
echo calc/custom/$$i; \
done
## ##
# #

View File

@@ -108,7 +108,6 @@ static struct infoname sys_info[] = {
{"MAXLABELS", "max number of user labels in function", NULL, (FULL)MAXLABELS}, {"MAXLABELS", "max number of user labels in function", NULL, (FULL)MAXLABELS},
{"MAXLEN", "longest storage size allowed", NULL, (FULL)MAXLEN}, {"MAXLEN", "longest storage size allowed", NULL, (FULL)MAXLEN},
{"MAXLONG", "largest long val", NULL, (FULL)MAXLONG}, {"MAXLONG", "largest long val", NULL, (FULL)MAXLONG},
{"MAXOBJECTS", "max number of object types", NULL, (FULL)MAXOBJECTS},
{"MAXPRINT_DEFAULT", "default number of elements printed", NULL, (FULL)MAXPRINT_DEFAULT}, {"MAXPRINT_DEFAULT", "default number of elements printed", NULL, (FULL)MAXPRINT_DEFAULT},
{"MAXREDC", "number of entries in REDC cache", NULL, (FULL)MAXREDC}, {"MAXREDC", "number of entries in REDC cache", NULL, (FULL)MAXREDC},
{"MAXSCANCOUNT", "default max scan errors before an abort", NULL, (FULL)MAXSCANCOUNT}, {"MAXSCANCOUNT", "default max scan errors before an abort", NULL, (FULL)MAXSCANCOUNT},

View File

@@ -394,15 +394,11 @@ builtin: builtin.top builtin.end ../func.c funclist.sed
distlist: ${DISTLIST} distlist: ${DISTLIST}
${Q}for i in ${DISTLIST}; do \ ${Q}for i in ${DISTLIST}; do \
echo calc/help/$$i; \ echo help/$$i; \
done | ${SORT} done | ${SORT}
# The bsdi distribution has generated files as well as distributed files. distdir:
# ${Q}echo help
bsdilist: ${DISTLIST} ${BLT_HELP_FILES}
${Q}for i in ${DISTLIST} ${BLT_HELP_FILES}; do \
echo calc/help/$$i; \
done | ${SORT}
# The BSDI cdrom makefile expects all help files to be pre-built. This rule # The BSDI cdrom makefile expects all help files to be pre-built. This rule
# creats these fils so that the release can be shipped off to BSDI. You can # creats these fils so that the release can be shipped off to BSDI. You can

View File

@@ -40,8 +40,8 @@ Configuration parameters
"blkverbose" TRUE=>print all lines, FALSE=>skip duplicates "blkverbose" TRUE=>print all lines, FALSE=>skip duplicates
"blkbase" block output base "blkbase" block output base
"blkfmt" block output format "blkfmt" block output format
"lib_debug" controls library script debug information
"calc_debug" controls internal calc debug information "calc_debug" controls internal calc debug information
"lib_debug" controls library script debug information
"user_debug" for user defined debug information "user_debug" for user defined debug information
"verbose_quit" TRUE=>print message on empty quit or abort "verbose_quit" TRUE=>print message on empty quit or abort
@@ -317,29 +317,6 @@ Configuration parameters
The default "blkfmt" is "hd". The default "blkfmt" is "hd".
The "lib_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc scripts.
Zero value of config("lib_debug") means that no such information
is displayed. For other values, the non-zero bits which currently
have meanings are as follows:
n Meaning of bit n of config("lib_debug")
0 When a function is defined, redefined or undefined at
interactive level, a message saying what has been done
is displayed.
1 When a function is defined, redefined or undefined during
the reading of a file, a message saying what has been done
is displayed.
The value for config("lib_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("lib_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.
The "calc_debug" is intended for controlling internal calc routines The "calc_debug" is intended for controlling internal calc routines
that test its operation, or collect or display information that that test its operation, or collect or display information that
might be useful for debug purposes. Much of the output from these might be useful for debug purposes. Much of the output from these
@@ -364,7 +341,42 @@ Configuration parameters
block is not NULL, and that its "length" is not negative. block is not NULL, and that its "length" is not negative.
A failure will result in a runtime error. A failure will result in a runtime error.
Bits >= 4 are reserved for future use and should not be used at this time. 4 Report on changes to the state of stdin as well as changes
to internal variables that control the setting and restoring
of stdin.
5 Report on changes to the run state of calc.
Bits >= 6 are reserved for future use and should not be used at this time.
By default, "calc_debug" is 0. The initial value may be overridden
by the -D command line option.
The "lib_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc scripts.
Zero value of config("lib_debug") means that no such information
is displayed. For other values, the non-zero bits which currently
have meanings are as follows:
n Meaning of bit n of config("lib_debug")
0 When a function is defined, redefined or undefined at
interactive level, a message saying what has been done
is displayed.
1 When a function is defined, redefined or undefined during
the reading of a file, a message saying what has been done
is displayed.
The value for config("lib_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("lib_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.
By default, "lib_debug" is 3. The -d flag changes this default to 0.
The initial value may be overridden by the -D command line option.
The "user_debug" is provided for use by users. Calc ignores this value The "user_debug" is provided for use by users. Calc ignores this value
other than to set it to 0 by default (for both "oldstd" and "newstd"). other than to set it to 0 by default (for both "oldstd" and "newstd").
@@ -376,6 +388,9 @@ Configuration parameters
slower operation or more memory usage, and a particular value (like slower operation or more memory usage, and a particular value (like
-1 or 0) corresponding to "no tests". -1 or 0) corresponding to "no tests".
By default, "user_debug" is 0. The initial value may be overridden
by the -D command line option.
The "verbose_quit" controls the print of the message: The "verbose_quit" controls the print of the message:
Quit or abort executed Quit or abort executed

View File

@@ -58,6 +58,10 @@ Environment variables
a terminal, then calc will still run, but fancy command line a terminal, then calc will still run, but fancy command line
editing is disabled. editing is disabled.
NOTE: If calc was compiled with GNU-readline support, the
CALCBINDINGS facility is ignored and the standard
readline mechanisms (see readline(3)) are used.
HOME HOME
This value is taken to be the home directory of the This value is taken to be the home directory of the

View File

@@ -2,8 +2,8 @@ Calc command line
Calc has the following command line: Calc has the following command line:
calc [-c] [-C] [-d] [-e] [-h] [-i] [-m mode] calc [-c] [-C] [-d] [-D calc_debug[:lib_debug:[user_debug]]]
[-n] [-p] [-q] [-u] [-v] [calc_cmd ...] [-e] [-h] [-i] [-m mode] [-n] [-p] [-q] [-u] [-v] [calc_cmd ...]
-c Continue reading command lines even after an execution -c Continue reading command lines even after an execution
error has caused the abandonment of a line. error has caused the abandonment of a line.
@@ -55,6 +55,22 @@ Calc command line
This flag disables the reporting of missing calc This flag disables the reporting of missing calc
startup scripts ($CALCRC). startup scripts ($CALCRC).
-D calc_debug[:lib_debug:[user_debug]]
Force the initial value of config("calc_debug"),
config("lib_debug") and config("user_debug").
The : separated strings are interpreted as signed 32 bit values.
After an optional leading sign a leading zero indicates octal
conversion, and a leading ``0x'' or ``0X'' hexadecimal
conversion. Otherwise, decimal conversion is assumed.
By default, calc_debug is 0, lib_debug is 3 and lib_debug is 0.
For more information use the following calc command:
help config
-e Ignore any environment variables on startup. The -e Ignore any environment variables on startup. The
getenv() builtin will still return values, however. getenv() builtin will still return values, however.

132
hist.c
View File

@@ -5,6 +5,8 @@
* *
* Adapted from code written by Stephen Rothwell. * Adapted from code written by Stephen Rothwell.
* *
* GNU readline support added by Martin Buck <mbuck@debian.org>
*
* Interactive readline module. This is called to read lines of input, * Interactive readline module. This is called to read lines of input,
* while using emacs-like editing commands within a command stack. * while using emacs-like editing commands within a command stack.
* The key bindings for the editing commands are (slightly) configurable. * The key bindings for the editing commands are (slightly) configurable.
@@ -48,6 +50,8 @@
# include <string.h> # include <string.h>
#endif #endif
#if !defined(USE_READLINE)
extern FILE *curstream(void); extern FILE *curstream(void);
#define STDIN 0 #define STDIN 0
@@ -283,11 +287,16 @@ hist_init(char *filename)
{ {
TTYSTRUCT newtty; TTYSTRUCT newtty;
if (inited) if (inited) {
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: inited already set in hist_init\n");
return HIST_INITED; return HIST_INITED;
}
inited = 1; inited = 1;
canedit = 0; canedit = 0;
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: Set inited, cleared canedit in hist_init\n");
/* /*
* open the bindings file * open the bindings file
@@ -309,20 +318,31 @@ hist_init(char *filename)
closeinput(); closeinput();
#ifdef USE_SGTTY #ifdef USE_SGTTY
if (ioctl(STDIN, TIOCGETP, &oldtty) < 0) if (ioctl(STDIN, TIOCGETP, &oldtty) < 0) {
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: Cannot TIOCGETP stdin in hist_init\n");
return HIST_NOTTY; return HIST_NOTTY;
}
newtty = oldtty; newtty = oldtty;
newtty.sg_flags &= ~ECHO; newtty.sg_flags &= ~ECHO;
newtty.sg_flags |= CBREAK; newtty.sg_flags |= CBREAK;
if (ioctl(STDIN, TIOCSETP, &newtty) < 0) if (ioctl(STDIN, TIOCSETP, &newtty) < 0) {
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: Cannot TIOCSETP stdin in hist_init\n");
return HIST_NOTTY; return HIST_NOTTY;
}
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: stty -ECHO +CBREAK in hist_init\n");
#endif #endif
#ifdef USE_TERMIO #ifdef USE_TERMIO
if (ioctl(STDIN, TCGETA, &oldtty) < 0) if (ioctl(STDIN, TCGETA, &oldtty) < 0) {
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: Cannot TCGETA stdin in hist_init\n");
return HIST_NOTTY; return HIST_NOTTY;
}
newtty = oldtty; newtty = oldtty;
newtty.c_lflag &= ~(ECHO | ECHOE | ECHOK); newtty.c_lflag &= ~(ECHO | ECHOE | ECHOK);
@@ -331,13 +351,22 @@ hist_init(char *filename)
newtty.c_cc[VMIN] = 1; newtty.c_cc[VMIN] = 1;
newtty.c_cc[VTIME] = 0; newtty.c_cc[VTIME] = 0;
if (ioctl(STDIN, TCSETAW, &newtty) < 0) if (ioctl(STDIN, TCSETAW, &newtty) < 0) {
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: Cannot TCSETAW stdin in hist_init\n");
return HIST_NOTTY; return HIST_NOTTY;
}
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: stty -ECHO -ECHOE -ECHOK -ICANON +ISTRIP "
"VMIN=1 VTIME=0 in hist_init\n");
#endif #endif
#ifdef USE_TERMIOS #ifdef USE_TERMIOS
if (tcgetattr(STDIN, &oldtty) < 0) if (tcgetattr(STDIN, &oldtty) < 0) {
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: Cannot tcgetattr stdin in hist_init\n");
return HIST_NOTTY; return HIST_NOTTY;
}
newtty = oldtty; newtty = oldtty;
newtty.c_lflag &= ~(ECHO | ECHOE | ECHOK); newtty.c_lflag &= ~(ECHO | ECHOE | ECHOK);
@@ -346,11 +375,19 @@ hist_init(char *filename)
newtty.c_cc[VMIN] = 1; newtty.c_cc[VMIN] = 1;
newtty.c_cc[VTIME] = 0; newtty.c_cc[VTIME] = 0;
if (tcsetattr(STDIN, TCSANOW, &newtty) < 0) if (tcsetattr(STDIN, TCSANOW, &newtty) < 0) {
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: Cannot tcsetattr stdin in hist_init\n");
return HIST_NOTTY; return HIST_NOTTY;
}
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: stty -ECHO -ECHOE -ECHOK -ICANON +ISTRIP "
"VMIN=1 VTIME=0 in hist_init\n");
#endif #endif
canedit = 1; canedit = 1;
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: Set canedit in hist_init\n");
return HIST_SUCCESS; return HIST_SUCCESS;
} }
@@ -363,20 +400,36 @@ void
hist_term(void) hist_term(void)
{ {
if (!inited || !canedit) { if (!inited || !canedit) {
if (conf->calc_debug & CALCDBG_TTY) {
if (!inited)
printf("DEBUG: inited already cleared "
"in hist_term\n");
if (!canedit)
printf("DEBUG: canedit already cleared "
"in hist_term\n");
}
inited = 0; inited = 0;
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: Cleared inited in hist_term\n");
return; return;
} }
#ifdef USE_SGTTY #ifdef USE_SGTTY
(void) ioctl(STDIN, TIOCSETP, &oldtty); (void) ioctl(STDIN, TIOCSETP, &oldtty);
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: TIOCSETP restored stdin in hist_term\n");
#endif #endif
#ifdef USE_TERMIO #ifdef USE_TERMIO
(void) ioctl(STDIN, TCSETAW, &oldtty); (void) ioctl(STDIN, TCSETAW, &oldtty);
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: TCSETAW restored stdin in hist_term\n");
#endif #endif
#ifdef USE_TERMIOS #ifdef USE_TERMIOS
(void) tcsetattr(STDIN, TCSANOW, &oldtty); (void) tcsetattr(STDIN, TCSANOW, &oldtty);
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: TCSANOW restored stdin in hist_term\n");
#endif #endif
} }
@@ -1384,8 +1437,68 @@ quit_calc(void)
exit(0); exit(0);
} }
#else /* USE_READLINE */
#ifdef HIST_TEST
#include <readline.h>
#include <history.h>
/*
* The readline/history libs do most of the dirty work for us, so we can
* replace hist_init() and hist_term() with dummies when using readline.
* For hist_getline() we have to add a newline that readline removed but
* calc expects. For hist_saveline(), we have to undo this. hist_getline()
* also has to cope with the different memory management schemes of calc and
* readline.
*/
int
hist_getline(char *prompt, char *buf, int len)
{
char *line;
buf[0] = '\0';
line = readline(prompt);
if (!line)
return 0;
strncpy(buf, line, len - 1);
buf[len - 2] = '\0';
len = strlen(buf);
buf[len] = '\n';
buf[len + 1] = '\0';
free(line);
return len + 1;
}
int
hist_init(char *filename)
{
return HIST_SUCCESS;
}
void
hist_term(void)
{
}
void
hist_saveline(char *line, int len)
{
if (!len)
return;
line[len - 1] = '\0';
add_history(line);
line[len - 1] = '\n';
}
#endif /* USE_READLINE */
#if defined(HIST_TEST)
/* /*
* Main routine to test history. * Main routine to test history.
@@ -1426,6 +1539,5 @@ main(int argc, char **argv)
hist_term(); hist_term();
exit(0); exit(0);
} }
#endif
/* END CODE */ #endif /* HIST_TEST */

View File

@@ -73,15 +73,11 @@ all: ${CALC_FILES} ${MAKE_FILE} .all
distlist: ${DISTLIST} distlist: ${DISTLIST}
${Q}for i in ${DISTLIST}; do \ ${Q}for i in ${DISTLIST}; do \
echo calc/lib/$$i; \ echo lib/$$i; \
done done
# The bsdi distribution has generated files as well as distributed files. distdir:
# ${Q}echo lib
bsdilist: ${DISTLIST}
${Q}for i in ${DISTLIST}; do \
echo calc/lib/$$i; \
done
clean: clean:

View File

@@ -1,4 +1,8 @@
# Alternate key bindings for calc line editing functions # Alternate key bindings for calc line editing functions
#
# NOTE: This facility is ignored if calc was compiled with GNU-readline.
# In that case, the standard readline mechanisms (see readline(3))
# are used in place of those found below.
map base-map map base-map
default insert-char default insert-char

View File

@@ -1,4 +1,8 @@
# Default key bindings for calc line editing functions # Default key bindings for calc line editing functions
#
# NOTE: This facility is ignored if calc was compiled with GNU-readline.
# In that case, the standard readline mechanisms (see readline(3))
# are used in place of those found below.
map base-map map base-map
default insert-char default insert-char

View File

@@ -20,18 +20,17 @@ print '002: Within each section, output should be numbered sequentially';
global prob; /* libregress.cal problem counter */ global prob; /* libregress.cal problem counter */
prob = 0; /* clear problem counter */ prob = 0; /* clear problem counter */
global junk; /* throw away value */ errcount(0),; /* clear error count */
junk = errcount(0); /* clear error count */ errmax(-1),; /* prevent errcount from abouting */
junk = errmax(-1); /* prevent errcount from abouting */
global ecnt; /* expected value of errcount() */ global ecnt; /* expected value of errcount() */
ecnt = 0; /* clear expected errcount() value */ ecnt = 0; /* clear expected errcount() value */
initcfg = config("all", "oldstd"); /* set config to startup default */ initcfg = config("all", "oldstd"); /* set config to startup default */
initcfg = config("lib_debug", 0); /* disable lib startup messages */ config("lib_debug", 0),; /* disable lib startup messages */
initcfg = config("calc_debug", 0); /* disable internal debugging */ config("calc_debug", 0),; /* disable internal debugging */
initcnf = config("verbose_quit", 0); /* disable quit messages */ config("verbose_quit", 0),; /* disable quit messages */
initcfg = config("all"); /* save state for later use */ startcfg = config("all"); /* save state for later use */
print '003: parsed global definitions'; print '003: parsed global definitions';
@@ -292,7 +291,7 @@ define test_arithmetic()
vrfy(8/4==2, '404: 8 / 4 == 2'); vrfy(8/4==2, '404: 8 / 4 == 2');
vrfy(2^3==8, '405: 2 ^ 3 == 8'); vrfy(2^3==8, '405: 2 ^ 3 == 8');
vrfy(9-4-2==3, '406: 9-4-2 == 3'); vrfy(9-4-2==3, '406: 9-4-2 == 3');
vrfy(9-4+2==7, '407: 9-4+2 == 6'); vrfy(9-4+2==7, '407: 9-4+2 == 7');
vrfy(-5+2==-3, '408: -5+2 == -3'); vrfy(-5+2==-3, '408: -5+2 == -3');
vrfy(2*3+1==7, '409: 2*3+1 == 7'); vrfy(2*3+1==7, '409: 2*3+1 == 7');
vrfy(1+2*3==7, '410: 1+2*3 == 7'); vrfy(1+2*3==7, '410: 1+2*3 == 7');
@@ -359,7 +358,7 @@ define test_config()
print '502: callcfg = config("all","oldstd")'; print '502: callcfg = config("all","oldstd")';
oldcfg = config("all", "newstd"); oldcfg = config("all", "newstd");
print '503: oldcfg = config("all","newstd")'; print '503: oldcfg = config("all","newstd")';
vrfy(callcfg == initcfg, '504: callcfg == initcfg'); vrfy(callcfg == startcfg, '504: callcfg == startcfg');
newcfg = config("all"); newcfg = config("all");
print '505: newcfg = config("all")'; print '505: newcfg = config("all")';
vrfy(config("all") == newcfg, '506: config("all") == newcfg'); vrfy(config("all") == newcfg, '506: config("all") == newcfg');
@@ -457,7 +456,7 @@ define test_config()
vrfy(config("all",callcfg) == oldcfg, vrfy(config("all",callcfg) == oldcfg,
'550: config("all",callcfg) == oldcfg'); '550: config("all",callcfg) == oldcfg');
vrfy(config("all") == callcfg, '551: config("all") == callcfg'); vrfy(config("all") == callcfg, '551: config("all") == callcfg');
vrfy(config("all") == initcfg, '552: config("all") == initcfg'); vrfy(config("all") == startcfg, '552: config("all") == startcfg');
print '553: Ending test_config'; print '553: Ending test_config';
} }

View File

@@ -63,9 +63,9 @@ int new_std = FALSE; /* TRUE (-n) => use newstd configuration */
int abortlevel; /* current level of aborts */ int abortlevel; /* current level of aborts */
BOOL inputwait; /* TRUE if in a terminal input wait */ BOOL inputwait; /* TRUE if in a terminal input wait */
jmp_buf jmpbuf; /* for errors */ jmp_buf jmpbuf; /* for errors */
run run_state = RUN_UNKNOWN; /* calc startup and run state */
char *program = "calc"; /* our name */ char *program = "calc"; /* our name */
char cmdbuf[MAXCMD+1+1+1]; /* command line expression + "\n\0" + guard */ char cmdbuf[MAXCMD+1+1+1]; /* command line expression + "\n\0" + guard */
run run_state = RUN_UNKNOWN; /* calc startup and run state */
/* /*
@@ -86,6 +86,7 @@ int d_flag = FALSE; /* TRUE => disable heading, lib_debug == 0 */
int c_flag = FALSE; /* TRUE => continue on error if permitted */ int c_flag = FALSE; /* TRUE => continue on error if permitted */
int i_flag = FALSE; /* TRUE => go interactive if permitted */ int i_flag = FALSE; /* TRUE => go interactive if permitted */
/* /*
* global values * global values
*/ */
@@ -106,6 +107,10 @@ int errmax = ERRMAX; /* if >= 0, maximum value for errcount */
NUMBER *epsilon_default; /* default allowed error for float calcs */ NUMBER *epsilon_default; /* default allowed error for float calcs */
char *calc_debug = NULL; /* !=NULL => value of config("calc_debug") */
char *lib_debug = NULL; /* !=NULL => value of config("lib_debug") */
char *user_debug = NULL; /* !=NULL => value of config("user_debug") */
/* /*
* initialization functions * initialization functions
@@ -173,6 +178,19 @@ libcalc_call_me_first(void)
conf->tab_ok = 0; conf->tab_ok = 0;
} }
/*
* -D flags can change calc_debug, lib_debug of user_debug
*/
if (calc_debug) {
conf->calc_debug = strtol(calc_debug, NULL, 0);
}
if (lib_debug) {
conf->lib_debug = strtol(lib_debug, NULL, 0);
}
if (user_debug) {
conf->user_debug = strtol(user_debug, NULL, 0);
}
/* /*
* initialize * initialize
*/ */
@@ -181,6 +199,11 @@ libcalc_call_me_first(void)
/* /*
* ready to rock & roll .. * ready to rock & roll ..
*/ */
if (conf->calc_debug & CALCDBG_RUNSTATE) {
printf("DEBUG: run_state from %s to %s\n",
run_state_name(run_state),
run_state_name(RUN_BEGIN));
}
run_state = RUN_BEGIN; run_state = RUN_BEGIN;
init_done = 1; init_done = 1;
return; return;
@@ -371,3 +394,33 @@ libcalc_call_me_last(void)
init_done = 0; init_done = 0;
return; return;
} }
/*
* run_state_name - return a constant string given a run_state
*/
char *
run_state_name(run state)
{
switch (state) {
case RUN_UNKNOWN:
return "RUN_UNKNOWN";
case RUN_BEGIN:
return "RUN_BEGIN";
case RUN_RCFILES:
return "RUN_RCFILES";
case RUN_PRE_CMD_ARGS:
return "RUN_PRE_CMD_ARGS";
case RUN_CMD_ARGS:
return "RUN_CMD_ARGS";
case RUN_PRE_TOP_LEVEL:
return "RUN_PRE_TOP_LEVEL";
case RUN_TOP_LEVEL:
return "RUN_TOP_LEVEL";
case RUN_EXIT:
return "RUN_EXIT";
case RUN_EXIT_WITH_ERROR:
return "RUN_EXIT_WITH_ERROR";
}
return "RUN_invalid";
}

34
obj.c
View File

@@ -96,8 +96,10 @@ static struct objectinfo {
static STRINGHEAD objectnames; /* names of objects */ static STRINGHEAD objectnames; /* names of objects */
static STRINGHEAD elements; /* element names for parts of objects */ static STRINGHEAD elements; /* element names for parts of objects */
static OBJECTACTIONS *objects[MAXOBJECTS]; /* table of actions for objects */ static OBJECTACTIONS **objects; /* table of actions for objects */
#define OBJALLOC 16
static long maxobjcount = 0;
static VALUE objpowi(VALUE *vp, NUMBER *q); static VALUE objpowi(VALUE *vp, NUMBER *q);
static BOOL objtest(OBJECT *op); static BOOL objtest(OBJECT *op);
@@ -456,11 +458,12 @@ objpowi(VALUE *vp, NUMBER *q)
* indices table of indices for elements * indices table of indices for elements
* count number of elements defined for the object * count number of elements defined for the object
*/ */
void int
defineobject(char *name, int indices[], int count) defineobject(char *name, int indices[], int count)
{ {
OBJECTACTIONS *oap; /* object definition structure */ OBJECTACTIONS *oap; /* object definition structure */
STRINGHEAD *hp; STRINGHEAD *hp;
OBJECTACTIONS **newobjects;
int index; int index;
hp = &objectnames; hp = &objectnames;
@@ -476,21 +479,32 @@ defineobject(char *name, int indices[], int count)
if (oap->count == count) { if (oap->count == count) {
for (index = 0; ; index++) { for (index = 0; ; index++) {
if (index >= count) if (index >= count)
return; return 0;
if (oap->elements[index] != indices[index]) if (oap->elements[index] != indices[index])
break; break;
} }
} }
math_error("Object type \"%s\" is already defined", name); return 1;
/*NOTREACHED*/
} }
if (hp->h_count >= MAXOBJECTS) { if (hp->h_count >= maxobjcount) {
math_error("Too many object types in use"); if (maxobjcount == 0) {
newobjects = (OBJECTACTIONS **) malloc(
OBJALLOC * sizeof(OBJECTACTIONS *));
maxobjcount = OBJALLOC;
} else {
maxobjcount += OBJALLOC;
newobjects = (OBJECTACTIONS **) realloc(objects,
maxobjcount * sizeof(OBJECTACTIONS *));
}
if (newobjects == NULL) {
math_error("Allocation failure for new object type");
/*NOTREACHED*/ /*NOTREACHED*/
} }
objects = newobjects;
}
oap = (OBJECTACTIONS *) malloc(objectactionsize(count)); oap = (OBJECTACTIONS *) malloc(objectactionsize(count));
if (oap)
name = addstr(hp, name); name = addstr(hp, name);
if ((oap == NULL) || (name == NULL)) { if ((oap == NULL) || (name == NULL)) {
math_error("Cannot allocate object type"); math_error("Cannot allocate object type");
@@ -504,7 +518,7 @@ defineobject(char *name, int indices[], int count)
oap->elements[index] = indices[index]; oap->elements[index] = indices[index];
index = findstr(hp, name); index = findstr(hp, name);
objects[index] = oap; objects[index] = oap;
return; return 0;
} }
@@ -596,7 +610,7 @@ objalloc(long index)
VALUE *vp; VALUE *vp;
int i; int i;
if ((unsigned) index >= MAXOBJECTS) { if (index < 0 || index > maxobjcount) {
math_error("Allocating bad object index"); math_error("Allocating bad object index");
/*NOTREACHED*/ /*NOTREACHED*/
} }

View File

@@ -404,8 +404,8 @@ config_hash(CONFIG *cfg, QCKHASH val)
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->blkverbose); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->blkverbose);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->blkbase); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->blkbase);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->blkfmt); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->blkfmt);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->lib_debug);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->calc_debug); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->calc_debug);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->lib_debug);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->user_debug); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->user_debug);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->verbose_quit); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->verbose_quit);

View File

@@ -321,15 +321,11 @@ many_random: many_random.o ../libcalc.a
distlist: ${DISTLIST} distlist: ${DISTLIST}
${Q}for i in ${DISTLIST}; do \ ${Q}for i in ${DISTLIST}; do \
echo calc/sample/$$i; \ echo sample/$$i; \
done done
# The bsdi distribution has generated files as well as distributed files. distdir:
# ${Q}echo sample
bsdilist: ${DISTLIST}
${Q}for i in ${DISTLIST}; do \
echo calc/sample/$$i; \
done
## ##
# #

16
seed.c
View File

@@ -55,14 +55,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <setjmp.h> #include <setjmp.h>
#if !defined(__bsdi)
#include <ustat.h>
#endif /* __bsdi */
#if defined(__linux)
# include <fcntl.h>
# define DEV_URANDOM "/dev/urandom"
# define DEV_URANDOM_POOL 128
#endif /* __linux */
#include "qmath.h" #include "qmath.h"
#include "longbits.h" #include "longbits.h"
#include "have_ustat.h" #include "have_ustat.h"
@@ -71,6 +63,14 @@
#include "have_gettime.h" #include "have_gettime.h"
#include "have_getprid.h" #include "have_getprid.h"
#include "have_urandom.h" #include "have_urandom.h"
#if defined(HAVE_USTAT)
# include <ustat.h>
#endif /* HAVE_USTAT */
#if defined(HAVE_URANDOM)
# include <fcntl.h>
# define DEV_URANDOM "/dev/urandom"
# define DEV_URANDOM_POOL 16
#endif /* HAVE_URANDOM */
/* /*

View File

@@ -446,7 +446,7 @@ extern VALUE objcall(int action, VALUE *v1, VALUE *v2, VALUE *v3);
extern void objfree(OBJECT *op); extern void objfree(OBJECT *op);
extern void objuncache(void); extern void objuncache(void);
extern int addelement(char *name); extern int addelement(char *name);
extern void defineobject(char *name, int indices[], int count); extern int defineobject(char *name, int indices[], int count);
extern int checkobject(char *name); extern int checkobject(char *name);
extern void showobjfuncs(void); extern void showobjfuncs(void);
extern void showobjtypes(void); extern void showobjtypes(void);

View File

@@ -12,7 +12,7 @@
#define MAJOR_VER 2 /* major version */ #define MAJOR_VER 2 /* major version */
#define MINOR_VER 11 /* minor version */ #define MINOR_VER 11 /* minor version */
#define MAJOR_PATCH 0 /* patch level or 0 if no patch */ #define MAJOR_PATCH 0 /* patch level or 0 if no patch */
#define MINOR_PATCH "9.1" /* test number or empty string if no patch */ #define MINOR_PATCH "9.3.1" /* test number or empty string if no patch */
/* /*
* calc version constants * calc version constants
@@ -80,3 +80,22 @@ version(void)
*/ */
return stored_version; return stored_version;
} }
#if defined(CALC_VER)
char *program; /* our name */
/*
* version - print the calc version
*/
/*ARGSUSED*/
int
main(int argc, char *argv[])
{
program = argv[0];
printf("%s\n", version());
return 0;
}
#endif /* CALC_VER */