Release calc version 2.11.0t10.4

This commit is contained in:
Landon Curt Noll
1999-11-18 05:43:44 -08:00
parent fbd3a79eba
commit 2c9b160dc5
26 changed files with 736 additions and 391 deletions

61
CHANGES
View File

@@ -44,7 +44,66 @@ The following are the changes from calc version 2.11.0t10 to date:
Added calcliblist and calcliblistfmt utility Makefile rules to allow Added calcliblist and calcliblistfmt utility Makefile rules to allow
one to print the list of distribution files that are used (but not one to print the list of distribution files that are used (but not
built) to form a .a calc library. built) to form either the libcalc.a or the libcustcalc.a library.
Added a patch from Randall.Gray@marine.csiro.au to make ^D terminate,
but *only* if the line it is on is completely empty. Removed lib/altbind
and removed the CALCBINDINGS Makefile variable.
A new config("ctrl_d") value controls how the ``delete_char'', which
by default is bound to ^D (Control D), will or will not exit calc:
config("ctrl_d", "virgin_eof")
If ^D is the only character that has been typed on a line,
then calc will exit. Otherwise ^D will act according to the
calc binding, which by default is a Emacs-style delete-char.
This is the default mode.
config("ctrl_d", "never_eof")
The ^D never exits calc and only acts according calc binding,
which by default is a Emacs-style delete-char.
Emacs purists may want to set this in their ~/.calcrc startup file.
config("ctrl_d", "empty_eof")
The ^D always exits calc if typed on an empty line. This
condition occurs when ^D either the first character typed,
or when all other characters on the line have been removed
(say by deleting them).
Users who always want to exit when ^D is typed at the beginning
of a line may want to set this in their ~/.calcrc startup file.
Note that config("ctrl_d") apples to the character bound to each
and every ``delete_char''. So if an alternate binding it setup,
then those char(s) will have this functionality.
Updated help/config and help/mode, improved the readability and
fixed a few typos. Documented modes, block formats and block bases
("mode", "blkfmt" & "blkbase") that were previously left off out of
the documentation.
The config("blkbase") and config("blkfmt") values return strings
instead of returning integers. One cannot use integers to set
these values, so returning integers was useless.
The following config values return "on" or "off" strings:
tilde tab leadzero fullzero blkverbose verbose_quit
These config values can still be set with same boolean strings
("on", "off", "true", "false", "t", ...) as well as via the
numerical values 0 (for "off") and non-0 (for "on"), however.
Applied the dangling name fix from Ernest Bowen <ernie@turing.une.edu.au>.
Show func prints function on order of their indices, and with
config("lib_debug") & 4 == 4 some more details about the functions
are displayed.
The following are the changes from calc version 2.11.0t8.9.1 to 2.11.0t9.4.5: The following are the changes from calc version 2.11.0t8.9.1 to 2.11.0t9.4.5:

View File

@@ -19,11 +19,6 @@ Installing calc in 4 easy steps:
As shipped the Makefile assumes 'more'. On your system As shipped the Makefile assumes 'more'. On your system
you may find 'less' to be a better pager. you may find 'less' to be a better pager.
The CALCBINDINGS is matter of personal taste. As shipped
the Makefile assumes a default quasi-emacs-like command
line editor. Changing CALCBINDINGS= altbind will cause ^D
to end calc in a fashion similar to that of the bc(1) command.
Set TOPDIR to be the place under which help files, calc, Set TOPDIR to be the place under which help files, calc,
include files and calc libs are to be installed. As shipped include files and calc libs are to be installed. As shipped
the Makefile assumes a TOPDIR of /usr/local/lib. the Makefile assumes a TOPDIR of /usr/local/lib.

View File

@@ -402,23 +402,11 @@ CALCPATH= .:./lib:~/lib:${LIBDIR}:${CUSTOMLIBDIR}
# #
CALCRC= ${LIBDIR}/startup:~/.calcrc CALCRC= ${LIBDIR}/startup:~/.calcrc
# If the $CALCBINDINGS environment variable is not defined, then the following
# file will be used for the command line and edit history key bindings.
# The $CALCPATH will be used to search for this file.
#
# ${LIBDIR}/bindings uses ^D for editing
# ${LIBDIR}/altbind uses ^D for EOF
#
# NOTE: This facility is disabled if USE_READLINE is set to -DUSE_READLINE.
#
CALCBINDINGS= bindings
#CALCBINDINGS= altbind
# Determine of the GNU-readline facility will be used instead of the # Determine of the GNU-readline facility will be used instead of the
# built-in CALCBINDINGS above. # built-in calc binding method.
# #
# USE_READLINE= Do not use GNU-readline, use CALCBINDINGS # USE_READLINE= Do not use GNU-readline, use calc bindings
# USE_READLINE= -DUSE_READLINE Use GNU-readline, do not use CALCBINDINGS # USE_READLINE= -DUSE_READLINE Use GNU-readline, do not use calc bindings
# #
# NOTE: If you select the 'USE_READLINE= -DUSE_READLINE' mode, you must set: # NOTE: If you select the 'USE_READLINE= -DUSE_READLINE' mode, you must set:
# #
@@ -1094,8 +1082,7 @@ calc.1: calc.man ${MAKE_FILE}
-rm -f calc.1 -rm -f calc.1
${SED} -e 's:$${LIBDIR}:${LIBDIR}:g' \ ${SED} -e 's:$${LIBDIR}:${LIBDIR}:g' \
-e 's,$${CALCPATH},${CALCPATH},g' \ -e 's,$${CALCPATH},${CALCPATH},g' \
-e 's,$${CALCRC},${CALCRC},g' \ -e 's,$${CALCRC},${CALCRC},g' < calc.man > calc.1
-e 's,$${CALCBINDINGS},${CALCBINDINGS},g' < calc.man > calc.1
## ##
# #
@@ -1159,11 +1146,6 @@ conf.h: ${MAKE_FILE}
${Q}echo '#define DEFAULTCALCRC "${CALCRC}"' >> conf.h ${Q}echo '#define DEFAULTCALCRC "${CALCRC}"' >> conf.h
${Q}echo '#endif /* DEFAULTCALCRC */' >> conf.h ${Q}echo '#endif /* DEFAULTCALCRC */' >> conf.h
${Q}echo '' >> conf.h ${Q}echo '' >> conf.h
${Q}echo '/* the default key bindings file */' >> conf.h
${Q}echo '#ifndef DEFAULTCALCBINDINGS' >> conf.h
${Q}echo '#define DEFAULTCALCBINDINGS "${CALCBINDINGS}"' >> conf.h
${Q}echo '#endif /* DEFAULTCALCBINDINGS */' >> conf.h
${Q}echo '' >> conf.h
${Q}echo '/* the location of the help directory */' >> conf.h ${Q}echo '/* the location of the help directory */' >> conf.h
${Q}echo '#ifndef HELPDIR' >> conf.h ${Q}echo '#ifndef HELPDIR' >> conf.h
${Q}echo '#define HELPDIR "${HELPDIR}"' >> conf.h ${Q}echo '#define HELPDIR "${HELPDIR}"' >> conf.h
@@ -2652,7 +2634,6 @@ env:
@echo "MANMAKE=${MANMAKE}"; echo "" @echo "MANMAKE=${MANMAKE}"; echo ""
@echo "CALCPATH=${CALCPATH}"; echo "" @echo "CALCPATH=${CALCPATH}"; echo ""
@echo "CALCRC=${CALCRC}"; echo "" @echo "CALCRC=${CALCRC}"; echo ""
@echo "CALCBINDINGS=${CALCBINDINGS}"; echo ""
@echo "CALCPAGER=${CALCPAGER}"; echo "" @echo "CALCPAGER=${CALCPAGER}"; echo ""
@echo "DEBUG=${DEBUG}"; echo "" @echo "DEBUG=${DEBUG}"; echo ""
@echo "NO_SHARED=${NO_SHARED}"; echo "" @echo "NO_SHARED=${NO_SHARED}"; echo ""
@@ -2964,6 +2945,7 @@ install: calc libcalc.a ${LIB_H_SRC} ${BUILD_H_SRC} calc.1
-rm -f ${LIBDIR}/libcalcerr.a libcalcerr.a -rm -f ${LIBDIR}/libcalcerr.a libcalcerr.a
-rm -f ${LIBDIR}/calc_errno.h calc_errno.h ${INCDIRCALC}/calc_errno.h -rm -f ${LIBDIR}/calc_errno.h calc_errno.h ${INCDIRCALC}/calc_errno.h
-rm -f calc_errno.c calc_errno.o calc_errno -rm -f calc_errno.c calc_errno.o calc_errno
-rm -f ${LIBDIR}/altbind ${HELPDIR}/altbind
${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-=' ${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-='
## ##

83
addop.c
View File

@@ -22,6 +22,7 @@
static long maxopcodes; /* number of opcodes available */ static long maxopcodes; /* number of opcodes available */
static long newindex; /* index of new function */ static long newindex; /* index of new function */
static char *newname; /* name of new function */
static long oldop; /* previous opcode */ static long oldop; /* previous opcode */
static long oldoldop; /* opcode before previous opcode */ static long oldoldop; /* opcode before previous opcode */
static long debugline; /* line number of latest debug opcode */ static long debugline; /* line number of latest debug opcode */
@@ -61,26 +62,49 @@ initfunctions(void)
void void
showfunctions(void) showfunctions(void)
{ {
FUNC **fpp; /* pointer into function table */
FUNC *fp; /* current function */ FUNC *fp; /* current function */
long count; long count;
long index;
count = 0; count = 0;
if (funccount > 0) { if (funccount > 0) {
for (fpp = &functions[funccount - 1]; fpp >= functions; fpp--) { if (conf->lib_debug & LIBDBG_FUNC_INFO)
fp = *fpp; math_str("Index\tName \tArgs\tOpcodes\n"
"-----\t------ \t---- \t------\n");
else
math_str("Name\tArguments\n"
"----\t---------\n");
for (index = 0; index < funccount; index++) {
fp = functions[index];
if (conf->lib_debug & LIBDBG_FUNC_INFO) {
math_fmt("%5ld\t%-12s\t", index,
namestr(&funcnames,index));
if (fp) {
count++;
math_fmt("%-5d\t%-5ld\n",
fp->f_paramcount, fp->f_opcodecount);
} else {
math_str("null\t0\n");
}
} else {
if (fp == NULL) if (fp == NULL)
continue; continue;
if (count++ == 0) { count++;
printf("Name Arguments\n---- ---------\n"); math_fmt("%-12s\t%-2d\n", namestr(&funcnames,
} index), fp->f_paramcount);
printf("%-12s %-2d\n", fp->f_name, fp->f_paramcount);
} }
} }
if (count > 0) { }
printf("\nNumber: %ld\n", count); if (conf->lib_debug & LIBDBG_FUNC_INFO) {
math_fmt("\nNumber non-null: %ld\n", count);
math_fmt("Number null: %ld\n", funccount - count);
math_fmt("Total number: %ld\n", funccount);
} else { } else {
printf("No user functions defined\n"); if (count > 0)
math_fmt("\nNumber: %ld\n", count);
else
math_str("No user functions defined\n");
} }
} }
@@ -115,7 +139,8 @@ beginfunc(char *name, BOOL newflag)
fp->f_opcodecount = 0; fp->f_opcodecount = 0;
fp->f_savedvalue.v_type = V_NULL; fp->f_savedvalue.v_type = V_NULL;
fp->f_savedvalue.v_subtype = V_NOSUBTYPE; fp->f_savedvalue.v_subtype = V_NOSUBTYPE;
fp->f_name = namestr(&funcnames, newindex); newname = namestr(&funcnames, newindex);
fp->f_name = newname;
curfunc = fp; curfunc = fp;
initlocals(); initlocals();
initlabels(); initlabels();
@@ -142,10 +167,11 @@ endfunc(void)
addop(OP_UNDEF); addop(OP_UNDEF);
addop(OP_RETURN); addop(OP_RETURN);
} }
checklabels(); checklabels();
if (errorcount) { if (errorcount) {
freefunc(curfunc); printf("\"%s\": %ld error%s\n", newname, errorcount,
printf("\"%s\": %ld error%s\n", curfunc->f_name, errorcount,
((errorcount == 1) ? "" : "s")); ((errorcount == 1) ? "" : "s"));
return; return;
} }
@@ -167,7 +193,7 @@ endfunc(void)
} }
if ((inputisterminal() && conf->lib_debug & LIBDBG_STDIN_FUNC) || if ((inputisterminal() && conf->lib_debug & LIBDBG_STDIN_FUNC) ||
(!inputisterminal() && conf->lib_debug & LIBDBG_FILE_FUNC)) { (!inputisterminal() && conf->lib_debug & LIBDBG_FILE_FUNC)) {
printf("%s(", fp->f_name); printf("%s(", newname);
for (index = 0; index < fp->f_paramcount; index++) { for (index = 0; index < fp->f_paramcount; index++) {
if (index) if (index)
putchar(','); putchar(',');
@@ -231,7 +257,7 @@ rmuserfunc(char *name)
index = findstr(&funcnames, name); index = findstr(&funcnames, name);
if (index < 0) { if (index < 0) {
printf("%s() has never been defined\n", fprintf(stderr, "%s() has never been defined\n",
name); name);
return; return;
} }
@@ -252,12 +278,25 @@ rmuserfunc(char *name)
void void
freefunc(FUNC *fp) freefunc(FUNC *fp)
{ {
long index;
long i; long i;
if (fp == NULL) if (fp == NULL)
return; return;
if (fp == curfunc) {
index = newindex;
} else {
for (index = 0; index < funccount; index++) {
if (functions[index] == fp)
break;
}
if (index == funccount) {
math_error("Bad call to freefunc!!!");
/*NOTREACHED*/
}
}
if (conf->traceflags & TRACE_FNCODES) { if (conf->traceflags & TRACE_FNCODES) {
printf("Freeing function \"%s\"\n", fp->f_name); printf("Freeing function \"%s\"\n",namestr(&funcnames,index));
dumpnames = FALSE; dumpnames = FALSE;
for (i = 0; i < fp->f_opcodecount; ) { for (i = 0; i < fp->f_opcodecount; ) {
printf("%ld: ", i); printf("%ld: ", i);
@@ -273,12 +312,14 @@ freefunc(FUNC *fp)
void void
rmalluserfunc(void) rmalluserfunc(void)
{ {
FUNC **fpp; FUNC *fp;
long index;
for (fpp = functions; fpp < &functions[funccount]; fpp++) { for (index = 0; index < funccount; index++) {
if (*fpp) { fp = functions[index];
freefunc(*fpp); if (fp) {
*fpp = NULL; freefunc(fp);
functions[index] = NULL;
} }
} }
} }

3
calc.h
View File

@@ -22,10 +22,11 @@
*/ */
#define CALCPATH "CALCPATH" /* environment variable for files */ #define CALCPATH "CALCPATH" /* environment variable for files */
#define CALCRC "CALCRC" /* environment variable for startup */ #define CALCRC "CALCRC" /* environment variable for startup */
#define CALCBINDINGS "CALCBINDINGS" /* environment variable for hist bindings */ #define CALCBINDINGS "CALCBINDINGS" /* env variable for hist bindings */
#define HOME "HOME" /* environment variable for home dir */ #define HOME "HOME" /* environment variable for home dir */
#define PAGER "PAGER" /* environment variable for help */ #define PAGER "PAGER" /* environment variable for help */
#define SHELL "SHELL" /* environment variable for shell */ #define SHELL "SHELL" /* environment variable for shell */
#define DEFAULTCALCBINDINGS "bindings" /* default calc bindings file */
#define DEFAULTCALCHELP "help" /* help file that -h prints */ #define DEFAULTCALCHELP "help" /* help file that -h prints */
#define DEFAULTSHELL "sh" /* default shell to use */ #define DEFAULTSHELL "sh" /* default shell to use */
#define CALCEXT ".cal" /* extension for files read in */ #define CALCEXT ".cal" /* extension for files read in */

View File

@@ -555,9 +555,10 @@ line, or \fI\-m\fP disallows opening files for reading),
reads reads
key bindings from the filename specified key bindings from the filename specified
by this environment variable. by this environment variable.
.br The key binding file is searched for along the $CALCPATH list
of directories.
.sp .sp
Default value: ${CALCBINDINGS} Default value: binding
.sp .sp
This variable is not used if calc was compiled with GNU-readline support. 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. In that case, the standard readline mechanisms (see readline(3)) are used.

317
config.c
View File

@@ -56,6 +56,8 @@ NAMETYPE configs[] = {
{"calc_debug", CONFIG_CALC_DEBUG}, {"calc_debug", CONFIG_CALC_DEBUG},
{"user_debug", CONFIG_USER_DEBUG}, {"user_debug", CONFIG_USER_DEBUG},
{"verbose_quit",CONFIG_VERBOSE_QUIT}, {"verbose_quit",CONFIG_VERBOSE_QUIT},
{"ctrl_d", CONFIG_CTRL_D},
{"ctrl-d", CONFIG_CTRL_D}, /* alias for ctrl_d */
{NULL, 0} {NULL, 0}
}; };
@@ -97,7 +99,8 @@ CONFIG oldstd = { /* backward compatible standard configuration */
0, /* internal calc debug level */ 0, /* internal calc debug level */
3, /* calc library 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 */
CTRL_D_VIRGIN /* ^D only exits on virgin lines */
}; };
CONFIG newstd = { /* new non-backward compatible configuration */ CONFIG newstd = { /* new non-backward compatible configuration */
MODE_INITIAL, /* current output mode */ MODE_INITIAL, /* current output mode */
@@ -133,7 +136,8 @@ CONFIG newstd = { /* new non-backward compatible configuration */
0, /* internal calc debug level */ 0, /* internal calc debug level */
3, /* calc library 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 */
CTRL_D_VIRGIN /* ^D only exits on virgin lines */
}; };
CONFIG *conf = NULL; /* loaded in at startup - current configuration */ CONFIG *conf = NULL; /* loaded in at startup - current configuration */
@@ -142,11 +146,15 @@ CONFIG *conf = NULL; /* loaded in at startup - current configuration */
* Possible output modes. * Possible output modes.
*/ */
static NAMETYPE modes[] = { static NAMETYPE modes[] = {
{"fraction", MODE_FRAC},
{"frac", MODE_FRAC}, {"frac", MODE_FRAC},
{"decimal", MODE_FRAC}, {"integer", MODE_INT},
{"dec", MODE_FRAC},
{"int", MODE_INT}, {"int", MODE_INT},
{"real", MODE_REAL}, {"real", MODE_REAL},
{"float", MODE_REAL},
{"default", MODE_INITIAL}, /* MODE_REAL */
{"scientific", MODE_EXP},
{"sci", MODE_EXP},
{"exp", MODE_EXP}, {"exp", MODE_EXP},
{"hexadecimal", MODE_HEX}, {"hexadecimal", MODE_HEX},
{"hex", MODE_HEX}, {"hex", MODE_HEX},
@@ -158,34 +166,13 @@ static NAMETYPE modes[] = {
}; };
/*
* Possible binary config state values
*/
static NAMETYPE truth[] = {
{"y", TRUE},
{"n", FALSE},
{"yes", TRUE},
{"no", FALSE},
{"set", TRUE},
{"unset", FALSE},
{"on", TRUE},
{"off", FALSE},
{"true", TRUE},
{"false", FALSE},
{"t", TRUE},
{"f", FALSE},
{"1", TRUE},
{"0", FALSE},
{NULL, 0}
};
/* /*
* Possible block base output modes * Possible block base output modes
*/ */
static NAMETYPE blk_base[] = { static NAMETYPE blk_base[] = {
{"hexadecimal", BLK_BASE_HEX}, {"hexadecimal", BLK_BASE_HEX},
{"hex", BLK_BASE_HEX}, {"hex", BLK_BASE_HEX},
{"default", BLK_BASE_HEX},
{"octal", BLK_BASE_OCT}, {"octal", BLK_BASE_OCT},
{"oct", BLK_BASE_OCT}, {"oct", BLK_BASE_OCT},
{"character", BLK_BASE_CHAR}, {"character", BLK_BASE_CHAR},
@@ -202,17 +189,60 @@ static NAMETYPE blk_base[] = {
* Possible block output formats * Possible block output formats
*/ */
static NAMETYPE blk_fmt[] = { static NAMETYPE blk_fmt[] = {
{"line", BLK_FMT_LINE},
{"lines", BLK_FMT_LINE}, {"lines", BLK_FMT_LINE},
{"str", BLK_FMT_STRING}, {"line", BLK_FMT_LINE},
{"string", BLK_FMT_STRING},
{"strings", BLK_FMT_STRING}, {"strings", BLK_FMT_STRING},
{"od", BLK_FMT_OD_STYLE}, {"string", BLK_FMT_STRING},
{"odstyle", BLK_FMT_OD_STYLE}, {"str", BLK_FMT_STRING},
{"od_style", BLK_FMT_OD_STYLE}, {"od_style", BLK_FMT_OD_STYLE},
{"hd", BLK_FMT_HD_STYLE}, {"odstyle", BLK_FMT_OD_STYLE},
{"hdstyle", BLK_FMT_HD_STYLE}, {"od", BLK_FMT_OD_STYLE},
{"hd_style", BLK_FMT_HD_STYLE}, {"hd_style", BLK_FMT_HD_STYLE},
{"hdstyle", BLK_FMT_HD_STYLE},
{"hd", BLK_FMT_HD_STYLE},
{"default", BLK_FMT_HD_STYLE},
{NULL, 0}
};
/*
* Possible ctrl_d styles
*/
static NAMETYPE ctrl_d[] = {
{"virgin_eof", CTRL_D_VIRGIN},
{"virgineof", CTRL_D_VIRGIN},
{"virgin", CTRL_D_VIRGIN},
{"default", CTRL_D_VIRGIN},
{"never_eof", CTRL_D_EMACS},
{"nevereof", CTRL_D_EMACS},
{"never", CTRL_D_EMACS},
{"empty_eof", CTRL_D_EOF},
{"emptyeof", CTRL_D_EOF},
{"empty", CTRL_D_EOF},
{NULL, 0}
};
/*
* Possible binary config state values
*/
#define TRUE_STRING "on"
#define FALSE_STRING "off"
static NAMETYPE truth[] = {
{TRUE_STRING, TRUE},
{"true", TRUE},
{"t", TRUE},
{"yes", TRUE},
{"y", TRUE},
{"set", TRUE},
{"1", TRUE},
{FALSE_STRING, FALSE},
{"false", FALSE},
{"f", FALSE},
{"no", FALSE},
{"n", FALSE},
{"unset", FALSE},
{"0", FALSE},
{NULL, 0} {NULL, 0}
}; };
@@ -220,11 +250,8 @@ static NAMETYPE blk_fmt[] = {
/* /*
* declate static functions * declate static functions
*/ */
static int modetype(char *name); static long lookup_long(NAMETYPE *set, char *name);
static int blkbase(char *name); static char *lookup_name(NAMETYPE *set, long val);
static int blkfmt(char *name);
static int truthtype(char *name);
static char *modename(int type);
/* /*
@@ -249,18 +276,21 @@ configtype(char *name)
/* /*
* Given the name of a mode, convert it to the internal format. * lookup_long - given a name and a NAMETYPE, return the int
* Returns -1 if the string is unknown.
* *
* given: * given:
* set the NAMESET array of name/int pairs
* name mode name * name mode name
*
* returns:
* numeric value of the name or -1 if not found
*/ */
static int static long
modetype(char *name) lookup_long(NAMETYPE *set, char *name)
{ {
NAMETYPE *cp; /* current config pointer */ NAMETYPE *cp; /* current config pointer */
for (cp = modes; cp->name; cp++) { for (cp = set; cp->name; cp++) {
if (strcmp(cp->name, name) == 0) if (strcmp(cp->name, name) == 0)
return cp->type; return cp->type;
} }
@@ -269,78 +299,22 @@ modetype(char *name)
/* /*
* Given the name of a block output base, convert it to the internal format. * lookup_name - given numeric value and a NAMETYPE, return the name
* Returns -1 if the string is unknown.
* *
* given: * given:
* name mode name * set the NAMESET array of name/int pairs
*/ * val numeric value to lookup
static int
blkbase(char *name)
{
NAMETYPE *cp; /* current config pointer */
for (cp = blk_base; cp->name; cp++) {
if (strcmp(cp->name, name) == 0)
return cp->type;
}
return -1;
}
/*
* Given the name of a block output format, convert it to the internal format.
* Returns -1 if the string is unknown.
* *
* given: * returns:
* name mode name * name of the value found of NULL
*/
static int
blkfmt(char *name)
{
NAMETYPE *cp; /* current config pointer */
for (cp = blk_fmt; cp->name; cp++) {
if (strcmp(cp->name, name) == 0)
return cp->type;
}
return -1;
}
/*
* Given the name of a truth value, convert it to a BOOL or -1.
* Returns -1 if the string is unknown.
*
* given:
* name mode name
*/
static int
truthtype(char *name)
{
NAMETYPE *cp; /* current config pointer */
for (cp = truth; cp->name; cp++) {
if (strcmp(cp->name, name) == 0)
return cp->type;
}
return -1;
}
/*
* Given the mode type, convert it to a string representing that mode.
* Where there are multiple strings representing the same mode, the first
* one in the table is used. Returns NULL if the node type is unknown.
* The returned string cannot be modified.
*/ */
static char * static char *
modename(int type) lookup_name(NAMETYPE *set, long val)
{ {
NAMETYPE *cp; /* current config pointer */ NAMETYPE *cp; /* current config pointer */
for (cp = modes; cp->name; cp++) { for (cp = set; cp->name; cp++) {
if (type == cp->type) if (val == cp->type)
return cp->name; return cp->name;
} }
return NULL; return NULL;
@@ -417,7 +391,7 @@ setconfig(int type, VALUE *vp)
math_error("Non-string for mode"); math_error("Non-string for mode");
/*NOTREACHED*/ /*NOTREACHED*/
} }
temp = modetype(vp->v_str->s_str); temp = lookup_long(modes, vp->v_str->s_str);
if (temp < 0) { if (temp < 0) {
math_error("Unknown mode \"%s\"", vp->v_str); math_error("Unknown mode \"%s\"", vp->v_str);
/*NOTREACHED*/ /*NOTREACHED*/
@@ -526,7 +500,7 @@ setconfig(int type, VALUE *vp)
q = vp->v_num; q = vp->v_num;
conf->tilde_ok = !qiszero(q); conf->tilde_ok = !qiszero(q);
} else if (vp->v_type == V_STR) { } else if (vp->v_type == V_STR) {
temp = truthtype(vp->v_str->s_str); temp = lookup_long(truth, vp->v_str->s_str);
if (temp < 0) { if (temp < 0) {
math_error("Illegal truth value for tilde"); math_error("Illegal truth value for tilde");
/*NOTREACHED*/ /*NOTREACHED*/
@@ -540,7 +514,7 @@ setconfig(int type, VALUE *vp)
q = vp->v_num; q = vp->v_num;
conf->tab_ok = !qiszero(q); conf->tab_ok = !qiszero(q);
} else if (vp->v_type == V_STR) { } else if (vp->v_type == V_STR) {
temp = truthtype(vp->v_str->s_str); temp = lookup_long(truth, vp->v_str->s_str);
if (temp < 0) { if (temp < 0) {
math_error("Illegal truth value for tab"); math_error("Illegal truth value for tab");
/*NOTREACHED*/ /*NOTREACHED*/
@@ -680,7 +654,7 @@ setconfig(int type, VALUE *vp)
q = vp->v_num; q = vp->v_num;
conf->leadzero = !qiszero(q); conf->leadzero = !qiszero(q);
} else if (vp->v_type == V_STR) { } else if (vp->v_type == V_STR) {
temp = truthtype(vp->v_str->s_str); temp = lookup_long(truth, vp->v_str->s_str);
if (temp < 0) { { if (temp < 0) { {
math_error("Illegal truth value for leadzero"); math_error("Illegal truth value for leadzero");
/*NOTREACHED*/ /*NOTREACHED*/
@@ -695,7 +669,7 @@ setconfig(int type, VALUE *vp)
q = vp->v_num; q = vp->v_num;
conf->fullzero = !qiszero(q); conf->fullzero = !qiszero(q);
} else if (vp->v_type == V_STR) { } else if (vp->v_type == V_STR) {
temp = truthtype(vp->v_str->s_str); temp = lookup_long(truth, vp->v_str->s_str);
if (temp < 0) { { if (temp < 0) { {
math_error("Illegal truth value for fullzero"); math_error("Illegal truth value for fullzero");
/*NOTREACHED*/ /*NOTREACHED*/
@@ -772,7 +746,7 @@ setconfig(int type, VALUE *vp)
q = vp->v_num; q = vp->v_num;
conf->blkverbose = !qiszero(q); conf->blkverbose = !qiszero(q);
} else if (vp->v_type == V_STR) { } else if (vp->v_type == V_STR) {
temp = truthtype(vp->v_str->s_str); temp = lookup_long(truth, vp->v_str->s_str);
if (temp < 0) { if (temp < 0) {
math_error("Illegal truth value for blkverbose"); math_error("Illegal truth value for blkverbose");
/*NOTREACHED*/ /*NOTREACHED*/
@@ -786,7 +760,7 @@ setconfig(int type, VALUE *vp)
math_error("Non-string for blkbase"); math_error("Non-string for blkbase");
/*NOTREACHED*/ /*NOTREACHED*/
} }
temp = blkbase(vp->v_str->s_str); temp = lookup_long(blk_base, vp->v_str->s_str);
if (temp < 0) { if (temp < 0) {
math_error("Unknown mode \"%s\" for blkbase", math_error("Unknown mode \"%s\" for blkbase",
vp->v_str->s_str); vp->v_str->s_str);
@@ -800,7 +774,7 @@ setconfig(int type, VALUE *vp)
math_error("Non-string for blkfmt"); math_error("Non-string for blkfmt");
/*NOTREACHED*/ /*NOTREACHED*/
} }
temp = blkfmt(vp->v_str->s_str); temp = lookup_long(blk_fmt, vp->v_str->s_str);
if (temp < 0) { if (temp < 0) {
math_error("Unknown mode \"%s\" for blkfmt", math_error("Unknown mode \"%s\" for blkfmt",
vp->v_str->s_str); vp->v_str->s_str);
@@ -856,9 +830,9 @@ setconfig(int type, VALUE *vp)
q = vp->v_num; q = vp->v_num;
conf->verbose_quit = !qiszero(q); conf->verbose_quit = !qiszero(q);
} else if (vp->v_type == V_STR) { } else if (vp->v_type == V_STR) {
temp = truthtype(vp->v_str->s_str); temp = lookup_long(truth, vp->v_str->s_str);
if (temp < 0) { if (temp < 0) {
math_error("Illegal truth value" math_error("Illegal truth value "
"for verbose_quit"); "for verbose_quit");
/*NOTREACHED*/ /*NOTREACHED*/
} }
@@ -866,6 +840,20 @@ setconfig(int type, VALUE *vp)
} }
break; break;
case CONFIG_CTRL_D:
if (vp->v_type != V_STR) {
math_error("Non-string for ctrl_d");
/*NOTREACHED*/
}
temp = lookup_long(ctrl_d, vp->v_str->s_str);
if (temp < 0) {
math_error("Unknown mode \"%s\" for ctrl_d",
vp->v_str->s_str);
/*NOTREACHED*/
}
conf->ctrl_d = temp;
break;
default: default:
math_error("Setting illegal config parameter"); math_error("Setting illegal config parameter");
/*NOTREACHED*/ /*NOTREACHED*/
@@ -986,6 +974,7 @@ void
config_value(CONFIG *cfg, int type, VALUE *vp) config_value(CONFIG *cfg, int type, VALUE *vp)
{ {
long i=0; long i=0;
char *p;
/* /*
* firewall * firewall
@@ -1017,7 +1006,12 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
case CONFIG_MODE: case CONFIG_MODE:
vp->v_type = V_STR; vp->v_type = V_STR;
vp->v_str = makenewstring(modename(cfg->outmode)); p = lookup_name(modes, cfg->outmode);
if (p == NULL) {
math_error("invalid output mode: %d", cfg->outmode);
/*NOTREACHED*/
}
vp->v_str = makenewstring(p);
return; return;
case CONFIG_EPSILON: case CONFIG_EPSILON:
@@ -1045,12 +1039,22 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
break; break;
case CONFIG_TILDE: case CONFIG_TILDE:
i = cfg->tilde_ok; vp->v_type = V_STR;
break; if (cfg->tilde_ok) {
vp->v_str = makenewstring(TRUE_STRING);
} else {
vp->v_str = makenewstring(FALSE_STRING);
}
return;
case CONFIG_TAB: case CONFIG_TAB:
i = cfg->tab_ok; vp->v_type = V_STR;
break; if (cfg->tab_ok) {
vp->v_str = makenewstring(TRUE_STRING);
} else {
vp->v_str = makenewstring(FALSE_STRING);
}
return;
case CONFIG_QUOMOD: case CONFIG_QUOMOD:
i = cfg->quomod; i = cfg->quomod;
@@ -1089,12 +1093,22 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
break; break;
case CONFIG_LEADZERO: case CONFIG_LEADZERO:
i = cfg->leadzero; vp->v_type = V_STR;
break; if (cfg->leadzero) {
vp->v_str = makenewstring(TRUE_STRING);
} else {
vp->v_str = makenewstring(FALSE_STRING);
}
return;
case CONFIG_FULLZERO: case CONFIG_FULLZERO:
i = cfg->fullzero; vp->v_type = V_STR;
break; if (cfg->fullzero) {
vp->v_str = makenewstring(TRUE_STRING);
} else {
vp->v_str = makenewstring(FALSE_STRING);
}
return;
case CONFIG_MAXSCAN: case CONFIG_MAXSCAN:
i = cfg->maxscancount; i = cfg->maxscancount;
@@ -1115,16 +1129,33 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
break; break;
case CONFIG_BLKVERBOSE: case CONFIG_BLKVERBOSE:
i = cfg->blkverbose; vp->v_type = V_STR;
break; if (cfg->blkverbose) {
vp->v_str = makenewstring(TRUE_STRING);
} else {
vp->v_str = makenewstring(FALSE_STRING);
}
return;
case CONFIG_BLKBASE: case CONFIG_BLKBASE:
i = cfg->blkbase; vp->v_type = V_STR;
break; p = lookup_name(blk_base, cfg->blkbase);
if (p == NULL) {
math_error("invalid block base: %d", cfg->blkbase);
/*NOTREACHED*/
}
vp->v_str = makenewstring(p);
return;
case CONFIG_BLKFMT: case CONFIG_BLKFMT:
i = cfg->blkfmt; vp->v_type = V_STR;
break; p = lookup_name(blk_fmt, cfg->blkfmt);
if (p == NULL) {
math_error("invalid block format: %d", cfg->blkfmt);
/*NOTREACHED*/
}
vp->v_str = makenewstring(p);
return;
case CONFIG_CALC_DEBUG: case CONFIG_CALC_DEBUG:
i = cfg->calc_debug; i = cfg->calc_debug;
@@ -1139,8 +1170,23 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
break; break;
case CONFIG_VERBOSE_QUIT: case CONFIG_VERBOSE_QUIT:
i = cfg->verbose_quit; vp->v_type = V_STR;
break; if (cfg->verbose_quit) {
vp->v_str = makenewstring(TRUE_STRING);
} else {
vp->v_str = makenewstring(FALSE_STRING);
}
return;
case CONFIG_CTRL_D:
vp->v_type = V_STR;
p = lookup_name(ctrl_d, cfg->ctrl_d);
if (p == NULL) {
math_error("invalid Control-D: %d", cfg->ctrl_d);
/*NOTREACHED*/
}
vp->v_str = makenewstring(p);
return;
default: default:
math_error("Getting illegal CONFIG element"); math_error("Getting illegal CONFIG element");
@@ -1218,5 +1264,6 @@ config_cmp(CONFIG *cfg1, CONFIG *cfg2)
cfg1->calc_debug != cfg2->calc_debug || cfg1->calc_debug != cfg2->calc_debug ||
cfg1->lib_debug != cfg2->lib_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 ||
cfg1->ctrl_d != cfg2->ctrl_d;
} }

View File

@@ -81,6 +81,7 @@
#define CONFIG_CALC_DEBUG 31 #define CONFIG_CALC_DEBUG 31
#define CONFIG_USER_DEBUG 32 #define CONFIG_USER_DEBUG 32
#define CONFIG_VERBOSE_QUIT 33 #define CONFIG_VERBOSE_QUIT 33
#define CONFIG_CTRL_D 34
/* /*
@@ -102,7 +103,9 @@
* *
* quickhash.c - config_hash() * quickhash.c - config_hash()
* hash.c - hash_value() * hash.c - hash_value()
* config.c - setconfig(), config_value(), config_cmp() * config.c - configs[], oldstd, newstd, setconfig(),
* config_value(), config_cmp()
* config.h - CONFIG_XYZ_SYMBOL (see above)
*/ */
struct config { struct config {
int outmode; /* current output mode */ int outmode; /* current output mode */
@@ -139,6 +142,7 @@ struct config {
long lib_debug; /* library debug, see LIB_DEBUG_XXX below */ long lib_debug; /* library debug, see LIB_DEBUG_XXX below */
long 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 */
int ctrl_d; /* see CTRL_D_xyz below */
}; };
typedef struct config CONFIG; typedef struct config CONFIG;
@@ -148,7 +152,8 @@ typedef struct config CONFIG;
*/ */
#define LIBDBG_STDIN_FUNC (0x00000001) /* interactive func define debug */ #define LIBDBG_STDIN_FUNC (0x00000001) /* interactive func define debug */
#define LIBDBG_FILE_FUNC (0x00000002) /* file read func define debug */ #define LIBDBG_FILE_FUNC (0x00000002) /* file read func define debug */
#define LIBDBG_MASK (0x00000003) #define LIBDBG_FUNC_INFO (0x00000004) /* print extra info for show func */
#define LIBDBG_MASK (0x00000007)
/* /*
@@ -162,6 +167,13 @@ typedef struct config CONFIG;
#define CALCDBG_RUNSTATE (0x00000020) /* report run_state changes */ #define CALCDBG_RUNSTATE (0x00000020) /* report run_state changes */
#define CALCDBG_MASK (0x0000003f) #define CALCDBG_MASK (0x0000003f)
/*
* ctrl-d meanings
*/
#define CTRL_D_VIRGIN (0) /* ^D only exits on virgin command lines */
#define CTRL_D_EMACS (1) /* ^D never exits, emacs binding meaning only */
#define CTRL_D_EOF (2) /* ^D always exits at start of line */
/* /*
* global configuration states and aliases * global configuration states and aliases

4
func.c
View File

@@ -6781,14 +6781,14 @@ f_blk(int count, VALUE **vals)
int chunk; /* block chunk size */ int chunk; /* block chunk size */
VALUE result; VALUE result;
int id; int id;
VALUE *vp; VALUE *vp = NULL;
int type; int type;
/* initialize VALUE */ /* initialize VALUE */
result.v_type = V_BLOCK; result.v_type = V_BLOCK;
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
type = 0; type = V_NULL;
if (count > 0) { if (count > 0) {
vp = *vals; vp = *vals;
type = vp->v_type; type = vp->v_type;

72
hash.c
View File

@@ -39,6 +39,15 @@ extern void shs1_init_state(HASH*);
extern void MD5_init_state(HASH*); extern void MD5_init_state(HASH*);
/*
* hash_long can deal with BOOL's, int's, FLAGS's and LEN's
*/
#define hash_bool(type, val, state) (hash_long((type), (long)(val), (state)))
#define hash_int(type, val, state) (hash_long((type), (long)(val), (state)))
#define hash_flag(type, val, state) (hash_long((type), (long)(val), (state)))
#define hash_len(type, val, state) (hash_long((type), (long)(val), (state)))
/* /*
* hash_setup - setup the hash state for a given hash * hash_setup - setup the hash state for a given hash
*/ */
@@ -257,6 +266,9 @@ hash_final(HASH *state)
* This function will hash a long value as if it were a 64 bit value. * This function will hash a long value as if it were a 64 bit value.
* The input is a long. If a long is smaller than 64 bits, we will * The input is a long. If a long is smaller than 64 bits, we will
* hash a final 32 bits of zeros. * hash a final 32 bits of zeros.
*
* This function is OK to hash BOOL's, unslogned long's, unsigned int's
* signed int's as well as FLAG's and LEN's.
*/ */
HASH * HASH *
hash_long(int type, long longval, HASH *state) hash_long(int type, long longval, HASH *state)
@@ -734,11 +746,10 @@ hash_value(int type, void *v, HASH *state)
(state->type)(value->v_type, state); (state->type)(value->v_type, state);
/* hash as if we have a 64 bit value */ /* hash as if we have a 64 bit value */
state = hash_long(type, (long)value->v_int, state); state = hash_int(type, value->v_int, state);
break; break;
case V_NUM: case V_NUM:
/* hash this type */ /* hash this type */
state = hash_number(type, value->v_num, state); state = hash_number(type, value->v_num, state);
break; break;
@@ -884,12 +895,12 @@ hash_value(int type, void *v, HASH *state)
(state->type)(value->v_type, state); (state->type)(value->v_type, state);
/* hash the RAND state */ /* hash the RAND state */
state = hash_long(type, (long)value->v_rand->seeded, state); state = hash_int(type, value->v_rand->seeded, state);
state = hash_long(type, (long)value->v_rand->bits, state); state = hash_int(type, value->v_rand->bits, state);
(state->update)(state, (state->update)(state,
(USB8 *)value->v_rand->buffer, SLEN*FULL_BITS/8); (USB8 *)value->v_rand->buffer, SLEN*FULL_BITS/8);
state = hash_long(type, (long)value->v_rand->j, state); state = hash_int(type, value->v_rand->j, state);
state = hash_long(type, (long)value->v_rand->k, state); state = hash_int(type, value->v_rand->k, state);
(state->update)(state, (state->update)(state,
(USB8 *)value->v_rand->slot, SCNT*FULL_BITS/8); (USB8 *)value->v_rand->slot, SCNT*FULL_BITS/8);
(state->update)(state, (state->update)(state,
@@ -903,8 +914,8 @@ hash_value(int type, void *v, HASH *state)
(state->type)(value->v_type, state); (state->type)(value->v_type, state);
/* hash the RANDOM state */ /* hash the RANDOM state */
state = hash_long(type, (long)value->v_random->seeded, state); state = hash_int(type, value->v_random->seeded, state);
state = hash_long(type, (long)value->v_random->bits, state); state = hash_int(type, value->v_random->bits, state);
(state->update)(state, (state->update)(state,
(USB8 *)&(value->v_random->buffer), BASEB/8); (USB8 *)&(value->v_random->buffer), BASEB/8);
state = hash_zvalue(type, value->v_random->r, state); state = hash_zvalue(type, value->v_random->r, state);
@@ -918,20 +929,19 @@ hash_value(int type, void *v, HASH *state)
(state->type)(value->v_type, state); (state->type)(value->v_type, state);
/* hash the CONFIG state */ /* hash the CONFIG state */
state = hash_long(type, (long)value->v_config->outmode, state); state = hash_int(type, value->v_config->outmode, state);
state = hash_long(type,(long)value->v_config->outdigits, state); state = hash_long(type,(long)value->v_config->outdigits, state);
state = hash_number(type, value->v_config->epsilon, state); state = hash_number(type, value->v_config->epsilon, state);
state = hash_long(type, state = hash_long(type,
(long)value->v_config->epsilonprec, state); (long)value->v_config->epsilonprec, state);
state = hash_long(type, state = hash_flag(type, value->v_config->traceflags, state);
(long)value->v_config->traceflags, state);
state = hash_long(type, (long)value->v_config->maxprint, state); state = hash_long(type, (long)value->v_config->maxprint, state);
state = hash_long(type, (long)value->v_config->mul2, state); state = hash_len(type, value->v_config->mul2, state);
state = hash_long(type, (long)value->v_config->sq2, state); state = hash_len(type, value->v_config->sq2, state);
state = hash_long(type, (long)value->v_config->pow2, state); state = hash_len(type, value->v_config->pow2, state);
state = hash_long(type, (long)value->v_config->redc2, state); state = hash_len(type, value->v_config->redc2, state);
state = hash_long(type, (long)value->v_config->tilde_ok, state); state = hash_bool(type, value->v_config->tilde_ok, state);
state = hash_long(type, (long)value->v_config->tab_ok, state); state = hash_bool(type, value->v_config->tab_ok, state);
state = hash_long(type, (long)value->v_config->quomod, state); state = hash_long(type, (long)value->v_config->quomod, state);
state = hash_long(type, (long)value->v_config->quo, state); state = hash_long(type, (long)value->v_config->quo, state);
state = hash_long(type, (long)value->v_config->mod, state); state = hash_long(type, (long)value->v_config->mod, state);
@@ -941,28 +951,26 @@ hash_value(int type, void *v, HASH *state)
state = hash_long(type, (long)value->v_config->cfsim, state); state = hash_long(type, (long)value->v_config->cfsim, state);
state = hash_long(type, (long)value->v_config->outround, state); state = hash_long(type, (long)value->v_config->outround, state);
state = hash_long(type, (long)value->v_config->round, state); state = hash_long(type, (long)value->v_config->round, state);
state = hash_long(type, (long)value->v_config->leadzero, state); state = hash_bool(type, value->v_config->leadzero, state);
state = hash_long(type, (long)value->v_config->fullzero, state); state = hash_bool(type, value->v_config->fullzero, state);
state = hash_long(type, state = hash_long(type,
(long)value->v_config->maxscancount, state); (long)value->v_config->maxscancount, state);
state = hash_str(type, value->v_config->prompt1, state); state = hash_str(type, value->v_config->prompt1, state);
state->bytes = FALSE; /* as if just read words */ state->bytes = FALSE; /* as if just read words */
state = hash_str(type, value->v_config->prompt2, state); state = hash_str(type, value->v_config->prompt2, state);
state->bytes = FALSE; /* as if just read words */ state->bytes = FALSE; /* as if just read words */
state = hash_long(type, state = hash_int(type, value->v_config->blkmaxprint, state);
(long)value->v_config->blkmaxprint, state); state = hash_bool(type, value->v_config->blkverbose, state);
state = hash_long(type, state = hash_int(type, value->v_config->blkbase, state);
(long)value->v_config->blkverbose, state); state = hash_int(type, value->v_config->blkfmt, state);
state = hash_long(type,
(long)value->v_config->blkbase, state);
state = hash_long(type,
(long)value->v_config->blkfmt, state);
state = hash_long(type, state = hash_long(type,
(long)value->v_config->lib_debug, state); (long)value->v_config->lib_debug, state);
state = hash_long(type, state = hash_long(type,
(long)value->v_config->calc_debug, state); (long)value->v_config->calc_debug, state);
state = hash_long(type, state = hash_long(type,
(long)value->v_config->user_debug, state); (long)value->v_config->user_debug, state);
state = hash_bool(type, value->v_config->verbose_quit, state);
state = hash_int(type, value->v_config->ctrl_d, state);
break; break;
case V_HASH: case V_HASH:
@@ -971,11 +979,11 @@ hash_value(int type, void *v, HASH *state)
(state->type)(value->v_type, state); (state->type)(value->v_type, state);
/* hash the HASH state */ /* hash the HASH state */
state = hash_long(type, (long)value->v_hash->type, state); state = hash_int(type, value->v_hash->type, state);
state = hash_long(type, (long)value->v_hash->bytes,state); state = hash_bool(type, value->v_hash->bytes,state);
state = hash_long(type, (long)value->v_hash->base, state); state = hash_int(type, value->v_hash->base, state);
state = hash_long(type, (long)value->v_hash->chunksize, state); state = hash_int(type, value->v_hash->chunksize, state);
state = hash_long(type, (long)value->v_hash->unionsize, state); state = hash_int(type, value->v_hash->unionsize, state);
(state->update)(state, (state->update)(state,
value->v_hash->h_union.data, state->unionsize); value->v_hash->h_union.data, state->unionsize);
state->bytes = FALSE; /* as if reading words */ state->bytes = FALSE; /* as if reading words */

View File

@@ -67,7 +67,7 @@ BLT_HELP_FILES_9= stdlib
STD_HELP_FILES_10= types usage unexpected variable STD_HELP_FILES_10= types usage unexpected variable
BLT_HELP_FILES_11= altbind bindings custom_cal libcalc new_custom stdlib BLT_HELP_FILES_11= bindings custom_cal libcalc new_custom stdlib
STD_HELP_FILES_12= archive STD_HELP_FILES_12= archive
@@ -175,18 +175,6 @@ bindings: ../lib/bindings
true; \ true; \
fi fi
altbind: ../lib/altbind
rm -f $@
cp ../lib/altbind $@
chmod 0444 $@
-@if [ -z "${Q}" ]; then \
echo ''; \
echo '=-=-= skipping the cat of help/$@ =-=-='; \
echo ''; \
else \
true; \
fi
stdlib: ../lib/README stdlib: ../lib/README
rm -f $@ rm -f $@
cp ../lib/README $@ cp ../lib/README $@

View File

@@ -18,19 +18,46 @@ DESCRIPTION
The following convention is used to declare modes: The following convention is used to declare modes:
base config base equivalent
value string config("mode")'s
2 "binary" binary fractions 2 "binary" base 2 fractions
8 "octal" octal fractions "bin"
10 "real" decimal floating point
16 "hex" hexadecimal fractions
-10 "int" decimal integer
1/3 "frac" decimal fractions
1e20 "exp" decimal exponential
For convenience, any non-integer value is assumed to mean "frac", 8 "octal" base 8 fractions
and any integer >= 2^64 is assumed to mean "exp". "oct"
10 "real" base 10 floating point
"float"
"default"
-10 "integer" base 10 integers
"int"
16 "hexadecimal" base 16 fractions
"hex"
1/3 "fraction" base 10 fractions
"frac"
1e20 "scientific" base 10 scientific notation
"sci"
"exp"
For convenience, any non-integer value is assumed to mean base 10
fractions and any integer >= 2^64 is assumed to mean base 10
scientific notation.
These base() calls have the same meaning as config("mode", "fraction"):
base(1/3) base(0.1415) base(16/37)
These base() calls have the same meaning as config("mode", "scientific"):
base(1e20) base(2^64) base(2^8191-1)
However the base() function will only return one of the base values
lised in the table above.
EXAMPLE EXAMPLE
> base() > base()

View File

@@ -44,7 +44,7 @@ Configuration parameters
"lib_debug" controls library script 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
"ctrl_d" The interactive meaning of ^D (Control D)
The "all" config value allows one to save/restore the configuration The "all" config value allows one to save/restore the configuration
set of values. The return of: set of values. The return of:
@@ -82,6 +82,43 @@ Configuration parameters
startup files; newstd may also be established by invoking calc startup files; newstd may also be established by invoking calc
with the flag -n. with the flag -n.
The following are synonyms for true:
"on"
"true"
"t"
"yes"
"y"
"set"
"1"
any non-zero number
The following are synonyms for false:
"off"
"false"
"f"
"no"
"n"
"unset"
"0"
the number zero (0)
Examples of setting some parameters are:
config("mode", "exp"); exponential output
config("display", 50); 50 digits of output
epsilon(epsilon() / 8); 3 bits more accuracy
config("tilde", 0) disable roundoff tilde printing
config("tab", "off") disable leading tab printing
Detailed config descriptions
=-=
config("trace", bitflag)
When nonzero, the "trace" parameter activates one or more features When nonzero, the "trace" parameter activates one or more features
that may be useful for debugging. These features correspond to that may be useful for debugging. These features correspond to
powers of 2 which contribute additively to config("trace"): powers of 2 which contribute additively to config("trace"):
@@ -101,6 +138,10 @@ Configuration parameters
See also lib_debug, calc_debug and user_debug below for more debug levels. See also lib_debug, calc_debug and user_debug below for more debug levels.
=-=
config("display", int)
The "display" parameter specifies the maximum number of digits after The "display" parameter specifies the maximum number of digits after
the decimal point to be printed in real or exponential mode in the decimal point to be printed in real or exponential mode in
normal unformatted printing (print, strprint, fprint) or in normal unformatted printing (print, strprint, fprint) or in
@@ -112,6 +153,11 @@ Configuration parameters
display up to d decimal places, the type of rounding to be used is display up to d decimal places, the type of rounding to be used is
controlled by config("outround"). controlled by config("outround").
=-=
config("epsilon", real)
epsilon(real)
The "epsilon" parameter specifies the default accuracy for the The "epsilon" parameter specifies the default accuracy for the
calculation of functions for which exact values are not possible or calculation of functions for which exact values are not possible or
not desired. For most functions, the not desired. For most functions, the
@@ -130,22 +176,58 @@ Configuration parameters
For the transcendental functions and the functions sqrt() and For the transcendental functions and the functions sqrt() and
appr(), the calculated value is always a multiple of epsilon. appr(), the calculated value is always a multiple of epsilon.
=-=
config("mode", "mode_string")
The "mode" parameter is a string specifying the mode for printing of The "mode" parameter is a string specifying the mode for printing of
numbers by the unformatted print functions, and the default numbers by the unformatted print functions, and the default
("%d" specifier) for formatted print functions. The initial mode ("%d" specifier) for formatted print functions. The initial mode
is "real". The available modes are: is "real". The available modes are:
"frac" decimal fractions config("mode") meaning equivalent
"int" decimal integer string base() call
"real" decimal floating point
"exp" decimal exponential "binary" base 2 fractions base(2)
"hex" hex fractions "bin"
"oct" octal fractions
"bin" binary fractions "octal" base 8 fractions base(8)
"oct"
"real" base 10 floating point base(10)
"float"
"default"
"integer" base 10 integer base(-10)
"int"
"hexadecimal" base 16 fractions base(16)
"hex"
"fraction" base 10 fractions base(1/3)
"frac"
"scientific" base 10 scientific notation base(1e20)
"sci"
"exp"
Where multiple strings are given, the first string listed is what
config("mode") will return.
The default "mode" is "real".
=-=
config("maxprint", int)
The "maxprint" parameter specifies the maximum number of elements to The "maxprint" parameter specifies the maximum number of elements to
be displayed when a matrix or list is printed. The initial value is 16. be displayed when a matrix or list is printed. The initial value is 16.
=-=
config("mul2", int)
config("sq2", int)
Mul2 and sq2 specify the sizes of numbers at which calc switches Mul2 and sq2 specify the sizes of numbers at which calc switches
from its first to its second algorithm for multiplying and squaring. from its first to its second algorithm for multiplying and squaring.
The first algorithm is the usual method of cross multiplying, which The first algorithm is the usual method of cross multiplying, which
@@ -163,6 +245,10 @@ Configuration parameters
the parameter back to its default value. Usually there is no need the parameter back to its default value. Usually there is no need
to change these parameters. to change these parameters.
=-=
config("pow2", int)
Pow2 specifies the sizes of numbers at which calc switches from Pow2 specifies the sizes of numbers at which calc switches from
its first to its second algorithm for calculating powers modulo its first to its second algorithm for calculating powers modulo
another number. The first algorithm for calculating modular powers another number. The first algorithm for calculating modular powers
@@ -171,6 +257,10 @@ Configuration parameters
which avoids divisions. The argument for pow2 is the size of the which avoids divisions. The argument for pow2 is the size of the
modulus at which the second algorithm begins to be used. modulus at which the second algorithm begins to be used.
=-=
config("redc2", int)
Redc2 specifies the sizes of numbers at which calc switches from Redc2 specifies the sizes of numbers at which calc switches from
its first to its second algorithm when using the REDC algorithm. its first to its second algorithm when using the REDC algorithm.
The first algorithm performs a multiply and a modular reduction The first algorithm performs a multiply and a modular reduction
@@ -179,16 +269,36 @@ Configuration parameters
O(N^1.585). The argument for redc2 is the size of the modulus at O(N^1.585). The argument for redc2 is the size of the modulus at
which the second algorithm begins to be used. which the second algorithm begins to be used.
=-=
config("tilde", boolean)
Config("tilde") controls whether or not a leading tilde ('~') is Config("tilde") controls whether or not a leading tilde ('~') is
printed to indicate that a number has not been printed exactly printed to indicate that a number has not been printed exactly
because the number of decimal digits required would exceed the because the number of decimal digits required would exceed the
specified maximum number. The initial "tilde" value is 1. specified maximum number. The initial "tilde" value is 1.
=-=
config("tab", boolean)
Config ("tab") controls the printing of a tab before results Config ("tab") controls the printing of a tab before results
automatically displayed when working interactively. It does not automatically displayed when working interactively. It does not
affect the printing by the functions print, printf, etc. The initial affect the printing by the functions print, printf, etc. The initial
"tab" value is 1. "tab" value is 1.
=-=
config("quomod", bitflag)
config("quo", bitflag)
config("mod", bitflag)
config("sqrt", bitflag)
config("appr", bitflag)
config("cfappr", bitflag)
config("cfsim", bitflag)
config("outround", bitflag)
config("round", bitflag)
The "quomod", "quo", "mod", "sqrt", "appr", "cfappr", "cfsim", and The "quomod", "quo", "mod", "sqrt", "appr", "cfappr", "cfsim", and
"round" control the way in which any necessary rounding occurs. "round" control the way in which any necessary rounding occurs.
Rounding occurs when for some reason, a calculated or displayed Rounding occurs when for some reason, a calculated or displayed
@@ -234,11 +344,19 @@ Configuration parameters
by the various kinds of printing to the output: bits 0, 1, 3 and 4 by the various kinds of printing to the output: bits 0, 1, 3 and 4
are used in the same way as for the functions round and bround. are used in the same way as for the functions round and bround.
=-=
config("leadzero", bool)
The "leadzero" parameter controls whether or not a 0 is printed The "leadzero" parameter controls whether or not a 0 is printed
before the decimal point in non-zero fractions with absolute value before the decimal point in non-zero fractions with absolute value
less than 1, e.g. whether 1/2 is printed as 0.5 or .5. The less than 1, e.g. whether 1/2 is printed as 0.5 or .5. The
initial value is 0, corresponding to the printing .5. initial value is 0, corresponding to the printing .5.
=-=
config("fullzero", bool)
The "fullzero" parameter controls whether or not in decimal floating- The "fullzero" parameter controls whether or not in decimal floating-
point printing, the digits are padded with zeros to reach the point printing, the digits are padded with zeros to reach the
number of digits specified by config("display") or by a precision number of digits specified by config("display") or by a precision
@@ -246,10 +364,18 @@ Configuration parameters
parameter is 0, so that, for example, if config("display") >= 2, parameter is 0, so that, for example, if config("display") >= 2,
5/4 will print in "real" mode as 1.25. 5/4 will print in "real" mode as 1.25.
=-=
config("maxscan", int)
The maxscan value controls how many scan errors are allowed The maxscan value controls how many scan errors are allowed
before the compiling phase of a computation is aborted. The initial before the compiling phase of a computation is aborted. The initial
value of "maxscan" is 20. Setting maxscan to 0 disables this feature. value of "maxscan" is 20. Setting maxscan to 0 disables this feature.
=-=
config("prompt", str)
The default prompt when in interactive mode is "> ". One may change The default prompt when in interactive mode is "> ". One may change
this prompt to a more cut-and-paste friendly prompt by: this prompt to a more cut-and-paste friendly prompt by:
@@ -259,17 +385,29 @@ Configuration parameters
cut/copy an input line and paste it directly into input. The cut/copy an input line and paste it directly into input. The
leading ';' will be ignored. leading ';' will be ignored.
=-=
config("more", str)
When inside multi-line input, the more prompt is used. One may When inside multi-line input, the more prompt is used. One may
change it by: change it by:
config("more", ";; ") config("more", ";; ")
=-=
config("blkmaxprint", int)
The "blkmaxprint" config value limits the number of octets to print The "blkmaxprint" config value limits the number of octets to print
for a block. A "blkmaxprint" of 0 means to print all octets of a for a block. A "blkmaxprint" of 0 means to print all octets of a
block, regardless of size. block, regardless of size.
The default is to print only the first 256 octets. The default is to print only the first 256 octets.
=-=
config("blkverbose", bool)
The "blkverbose" determines if all lines, including duplicates The "blkverbose" determines if all lines, including duplicates
should be printed. If TRUE, then all lines are printed. If false, should be printed. If TRUE, then all lines are printed. If false,
duplicate lines are skipped and only a "*" is printed in a style duplicate lines are skipped and only a "*" is printed in a style
@@ -278,11 +416,16 @@ Configuration parameters
The default value for "blkverbose" is FALSE: duplicate lines are The default value for "blkverbose" is FALSE: duplicate lines are
not printed. not printed.
=-=
config("blkbase", "blkbase_string")
The "blkbase" determines the base in which octets of a block The "blkbase" determines the base in which octets of a block
are printed. Possible values are: are printed. Possible values are:
"hexadecimal" Octets printed in 2 digit hex "hexadecimal" Octets printed in 2 digit hex
"hex" "hex"
"default"
"octal" Octets printed in 3 digit octal "octal" Octets printed in 3 digit octal
"oct" "oct"
@@ -296,26 +439,41 @@ Configuration parameters
"raw" Octets printed as is, i.e. raw binary "raw" Octets printed as is, i.e. raw binary
"none" "none"
The default "blkbase" is "hex". Where multiple strings are given, the first string listed is what
config("blkbase") will return.
The default "blkbase" is "hexadecimal".
=-=
config("blkfmt", "blkfmt_string")
The "blkfmt" determines for format of how block are printed: The "blkfmt" determines for format of how block are printed:
"line" print in lines of up to 79 chars + newline "lines" print in lines of up to 79 chars + newline
"lines" "line"
"str" print as one long string "strings" print as one long string
"string" "string"
"strings" "str"
"od" print in od-like format, with leading offset, "od_style" print in od-like format, with leading offset,
"odstyle" followed by octets in the given base "odstyle" followed by octets in the given base
"od_style" "od"
"hd" print in hex dump format, with leading offset, "hd_style" print in hex dump format, with leading offset,
"hdstyle" followed by octets in the given base, followed "hdstyle" followed by octets in the given base, followed
"hd_style" by chars or '.' if no-printable or blank "hd" by chars or '.' if no-printable or blank
"default"
The default "blkfmt" is "hd". Where multiple strings are given, the first string listed is what
config("blkfmt") will return.
The default "blkfmt" is "hd_style".
=-=
config("calc_debug", bitflag)
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
@@ -352,6 +510,10 @@ Configuration parameters
By default, "calc_debug" is 0. The initial value may be overridden By default, "calc_debug" is 0. The initial value may be overridden
by the -D command line option. by the -D command line option.
=-=
config("lib_debug", bitflag)
The "lib_debug" parameter is intended for controlling the possible The "lib_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and display of special information relating to functions, objects, and
other structures created by instructions in calc scripts. other structures created by instructions in calc scripts.
@@ -369,6 +531,9 @@ Configuration parameters
the reading of a file, a message saying what has been done the reading of a file, a message saying what has been done
is displayed. is displayed.
2 Show func will display more information about a functions
arguments as well as more argument sdummary information.
The value for config("lib_debug") in both oldstd and newstd is 3, 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. 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") Thus, if calc is started without the -d flag, until config("lib_debug")
@@ -378,6 +543,10 @@ Configuration parameters
By default, "lib_debug" is 3. The -d flag changes this default to 0. 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 initial value may be overridden by the -D command line option.
=-=
config("user_debug", int)
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").
No calc code or shipped library should change this value. Users No calc code or shipped library should change this value. Users
@@ -391,26 +560,44 @@ Configuration parameters
By default, "user_debug" is 0. The initial value may be overridden By default, "user_debug" is 0. The initial value may be overridden
by the -D command line option. by the -D command line option.
=-=
config("verbose_quit", bool)
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
when a non-interactive quit or abort without an argument is encounted. when a non-interactive quit or abort without an argument is encountered.
A quit of abort without an argument does not display a message when A quit of abort without an argument does not display a message when
invoked at the interactive level. invoked at the interactive level.
The following are synonyms for true: =-=
"on" "yes" "y" "true" "t" "1" any non-zero number config("ctrl_d", "ctrl_d_string")
The following are synonyms for false: The "ctrl_d" controls the interactive meaning of ^D (Control D):
"off" "no" "n" "false" "f" "0" the number zero (0) "virgin_eof" If ^D is the only character that has been typed
"virgineof" on a line, then calc will exit. Otherwise ^D
"virgin" will act according to the calc binding, which
"default" by default is a Emacs-style delete-char.
Examples of setting some parameters are: "never_eof" The ^D never exits calc and only acts according
"nevereof" calc binding, which by default is a Emacs-style
"never" delete-char.
config("mode", "exp"); exponential output "empty_eof" The ^D always exits calc if typed on an empty line.
config("display", 50); 50 digits of output "emptyeof" This condition occurs when ^D either the first
epsilon(epsilon() / 8); 3 bits more accuracy "empty" character typed, or when all other characters on
config("tilde", 0) disable roundoff tilde printing the line have been removed (say by deleting them).
config("tab", "off") disable leading tab printing
Where multiple strings are given, the first string listed is what
config("ctrl_d") will return.
Note that config("ctrl_d") actually controls each and every character
that is bound to ``delete_char''. By default, ``delete_char'' is
Control D. Any character(s) bound to ``delete_char'' will cause calc
to exit (or not exit) as directed by config("ctrl_d").
The default "ctrl_d" is "virgin_eof".

View File

@@ -48,8 +48,6 @@ Environment variables
Typically compiled in value is: Typically compiled in value is:
bindings bindings
or:
altbind (bindings where ^D means exit)
The bindings file is searched along the CALCPATH. Unlike The bindings file is searched along the CALCPATH. Unlike
the READ command, a .cal extension is not added. the READ command, a .cal extension is not added.

View File

@@ -30,7 +30,6 @@ following topics:
usage how to invoke the calc command usage how to invoke the calc command
variable variables and variable declarations variable variables and variable declarations
altbind alternative input & history character bindings
bindings input & history character bindings bindings input & history character bindings
custom_cal information about custom calc library files custom_cal information about custom calc library files
libcalc using the arbitrary precision routines in a C program libcalc using the arbitrary precision routines in a C program

View File

@@ -39,7 +39,6 @@ Very High priority items:
overview overview of calc overview overview of calc
assoc using associations assoc using associations
command top level commands command top level commands
config configuration parameters
define how to define functions define how to define functions
environment how environment variables effect calc environment how environment variables effect calc
errorcodes calc generated error codes errorcodes calc generated error codes

49
hist.c
View File

@@ -76,6 +76,7 @@ static struct {
int linelen; int linelen;
int histcount; int histcount;
int curhist; int curhist;
BOOL virgin_line; /* 1 => never typed chars, 0 => chars typed */
} HS; } HS;
@@ -250,9 +251,15 @@ static void insert_string(char *str, int len);
int int
hist_getline(char *prompt, char *buf, int len) hist_getline(char *prompt, char *buf, int len)
{ {
/*
* initialize if we have not already done so
*/
if (!inited) if (!inited)
(void) hist_init(calcbindings); (void) hist_init(calcbindings);
/*
* establish the beginning of a line condition
*/
HS.prompt = prompt; HS.prompt = prompt;
HS.bufsize = len - 2; HS.bufsize = len - 2;
HS.buf = buf; HS.buf = buf;
@@ -260,19 +267,38 @@ hist_getline(char *prompt, char *buf, int len)
HS.end = buf; HS.end = buf;
HS.mark = NULL; HS.mark = NULL;
HS.linelen = -1; HS.linelen = -1;
HS.virgin_line = TRUE;
/*
* prep the I/O
*/
fputs(prompt, stdout); fputs(prompt, stdout);
fflush(stdout); fflush(stdout);
/*
* special case: non-interactive editing
*/
if (!canedit) { if (!canedit) {
if (fgets(buf, len, stdin) == NULL) if (fgets(buf, len, stdin) == NULL)
return 0; return 0;
return strlen(buf); return strlen(buf);
} }
while (HS.linelen < 0) /*
* get the line
*/
while (HS.linelen < 0) {
/* get the next char */
read_key(); read_key();
/* chars typed, no longer virgin */
HS.virgin_line = FALSE;
}
/*
* return the line
*/
return HS.linelen; return HS.linelen;
} }
@@ -292,12 +318,18 @@ hist_init(char *filename)
{ {
TTYSTRUCT newtty; TTYSTRUCT newtty;
/*
* prevent multiple initializations
*/
if (inited) { if (inited) {
if (conf->calc_debug & CALCDBG_TTY) if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: inited already set in hist_init\n"); printf("DEBUG: inited already set in hist_init\n");
return HIST_INITED; return HIST_INITED;
} }
/*
* setup
*/
inited = 1; inited = 1;
canedit = 0; canedit = 0;
if (conf->calc_debug & CALCDBG_TTY) if (conf->calc_debug & CALCDBG_TTY)
@@ -984,6 +1016,21 @@ forward_kill_char(void)
static void static void
delete_char(void) delete_char(void)
{ {
/*
* quit delete_char (usually ^D) is at start of line and we are allowed
*
* We exit of start of line and config("ctrl_d", "empty") or
* if config("ctrl_d", "virgin") and we have never typed on the line.
*/
if ((HS.end == HS.buf) &&
(conf->ctrl_d == CTRL_D_EOF ||
(conf->ctrl_d == CTRL_D_VIRGIN && HS.virgin_line == TRUE))) {
quit_calc();
}
/*
* normal case: just forward_kill_char
*/
if (HS.end > HS.buf) if (HS.end > HS.buf)
forward_kill_char(); forward_kill_char();
} }

View File

@@ -39,7 +39,7 @@ CALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.cal \
lucas_tbl.cal mersenne.cal mod.cal pell.cal pi.cal pix.cal \ lucas_tbl.cal mersenne.cal mod.cal pell.cal pi.cal pix.cal \
pollard.cal poly.cal psqrt.cal quat.cal regress.cal solve.cal \ pollard.cal poly.cal psqrt.cal quat.cal regress.cal solve.cal \
sumsq.cal surd.cal unitfrac.cal varargs.cal chrem.cal mfactor.cal \ sumsq.cal surd.cal unitfrac.cal varargs.cal chrem.cal mfactor.cal \
bindings altbind randmprime.cal test1700.cal randrun.cal \ bindings randmprime.cal test1700.cal randrun.cal \
randbitrun.cal bernoulli.cal test2300.cal test2600.cal \ randbitrun.cal bernoulli.cal test2300.cal test2600.cal \
test2700.cal test3100.cal test3300.cal test3400.cal prompt.cal \ test2700.cal test3100.cal test3300.cal test3400.cal prompt.cal \
test3500.cal seedrandom.cal test4000.cal test4100.cal test4600.cal \ test3500.cal seedrandom.cal test4000.cal test4100.cal test4600.cal \

View File

@@ -1,49 +0,0 @@
# 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
default insert-char
^@ set-mark
^A start-of-line
^B backward-char
^D quit
^E end-of-line
^F forward-char
^H backward-kill-char
^J new-line
^K kill-line
^L refresh-line
^M new-line
^N forward-history
^O save-line
^P backward-history
^R reverse-search
^T swap-chars
^U flush-input
^V quote-char
^W kill-region
^Y yank
^? delete-char
^[ ignore-char esc-map
map esc-map
default ignore-char base-map
G start-of-line
H backward-history
P forward-history
K backward-char
M forward-char
O end-of-line
S delete-char
g goto-line
s backward-word
t forward-word
d forward-kill-word
u uppercase-word
l lowercase-word
h list-history
^[ flush-input
[ arrow-key

View File

@@ -385,10 +385,10 @@ define test_config()
'516: config("pow2") == 40'); '516: config("pow2") == 40');
vrfy(config("redc2") == 50, vrfy(config("redc2") == 50,
'517: config("redc2") == 50'); '517: config("redc2") == 50');
vrfy(config("tilde") == 1, vrfy(config("tilde") == "on",
'518: config("tilde") == 1'); '518: config("tilde") == "on"');
vrfy(config("tab") == 1, vrfy(config("tab") == "on",
'519: config("tab") == 1'); '519: config("tab") == "on"');
vrfy(config("quomod") == 0, vrfy(config("quomod") == 0,
'520: config("quomod") == 0'); '520: config("quomod") == 0');
vrfy(config("quo") == 2, vrfy(config("quo") == 2,
@@ -407,10 +407,10 @@ define test_config()
'527: config("outround") == 2'); '527: config("outround") == 2');
vrfy(config("round") == 24, vrfy(config("round") == 24,
'528: config("round") == 24'); '528: config("round") == 24');
vrfy(config("leadzero") == 0, vrfy(config("leadzero") == "off",
'529: config("leadzero") == 0'); '529: config("leadzero") == "off"');
vrfy(config("fullzero") == 0, vrfy(config("fullzero") == "off",
'530: config("fullzero") == 0'); '530: config("fullzero") == "off"');
vrfy(config("maxscan") == 20, vrfy(config("maxscan") == 20,
'531: config("maxscan") == 20'); '531: config("maxscan") == 20');
vrfy(config("prompt") == "> ", vrfy(config("prompt") == "> ",
@@ -426,10 +426,10 @@ define test_config()
vrfy(config("quo", 0) == 2, '536: config("quo", 0) == 2'); vrfy(config("quo", 0) == 2, '536: config("quo", 0) == 2');
vrfy(config("outround", 24) == 2, vrfy(config("outround", 24) == 2,
'537: config("outround", 24) == 2'); '537: config("outround", 24) == 2');
vrfy(config("leadzero", "y") == 0, vrfy(config("leadzero","y") == "off",
'538: config("leadzero", "y") == 0'); '538: config("leadzero","y") == "off"');
vrfy(config("fullzero", 1) == 0, vrfy(config("fullzero", 1) == "off",
'539: config("fullzero", 1) == 0'); '539: config("fullzero", 1) == "off"');
vrfy(config("prompt", "; ") == "> ", vrfy(config("prompt", "; ") == "> ",
'540: config("prompt", "; ") == "> "'); '540: config("prompt", "; ") == "> "');
vrfy(config("more", ";; ") == ">> ", vrfy(config("more", ";; ") == ">> ",
@@ -441,14 +441,14 @@ define test_config()
'543: config("all",callcfg) == newcfg'); '543: config("all",callcfg) == newcfg');
vrfy(config("display",2) == 20, vrfy(config("display",2) == 20,
'544: config("display",2) == 20'); '544: config("display",2) == 20');
vrfy(config("fullzero",1) == 0, vrfy(config("fullzero",1) == "off",
'545: config("fullzero",1) == 0'); '545: config("fullzero",1) == "off"');
vrfy(strprintf("%d %d %d", 0, 1, 2) == ".00 1.00 2.00", vrfy(strprintf("%d %d %d", 0, 1, 2) == ".00 1.00 2.00",
'546: strprintf("%d %d %d", 0, 1, 2) == ".00 1.00 2.00"'); '546: strprintf("%d %d %d", 0, 1, 2) == ".00 1.00 2.00"');
vrfy(config("display",20) == 2, vrfy(config("display",20) == 2,
'547: config("display",20) == 2'); '547: config("display",20) == 2');
vrfy(config("fullzero",0) == 1, vrfy(config("fullzero",0) == "on",
'548: config("fullzero",0) == 1'); '548: config("fullzero",0) == "on"');
vrfy(strprintf("%d %d %d", 0, 1, 2) == "0 1 2", vrfy(strprintf("%d %d %d", 0, 1, 2) == "0 1 2",
'549: strprintf("%d %d %d", 0, 1, 2) == "0 1 2"'); '549: strprintf("%d %d %d", 0, 1, 2) == "0 1 2"');
@@ -1582,12 +1582,12 @@ define test_mode()
tmp = config("mode", "int"); tmp = config("mode", "int");
print '1604: tmp = config("mode", "int")'; print '1604: tmp = config("mode", "int")';
vrfy(tmp == "frac", '1605: tmp == "frac"'); vrfy(tmp == "fraction", '1605: tmp == "fraction"');
vrfy(base() == -10, '1606: base() == -10'); vrfy(base() == -10, '1606: base() == -10');
tmp = config("mode", "real"); tmp = config("mode", "real");
print '1607: tmp = config("mode", "real")'; print '1607: tmp = config("mode", "real")';
vrfy(tmp == "int", '1608: tmp == "int"'); vrfy(tmp == "integer", '1608: tmp == "integer"');
vrfy(base() == 10, '1609: base() == 10'); vrfy(base() == 10, '1609: base() == 10');
tmp = config("mode", "exp"); tmp = config("mode", "exp");
@@ -1597,7 +1597,7 @@ define test_mode()
tmp = config("mode", "hex"); tmp = config("mode", "hex");
print '1613: tmp = config("mode", "hex")'; print '1613: tmp = config("mode", "hex")';
vrfy(tmp == "exp", '1614: tmp == "exp"'); vrfy(tmp == "scientific", '1614: tmp == "scientific"');
vrfy(base() == 16, '1615: base() == 16'); vrfy(base() == 16, '1615: base() == 16');
tmp = config("mode", "oct"); tmp = config("mode", "oct");
@@ -1616,11 +1616,13 @@ define test_mode()
tmp = base(1/3); tmp = base(1/3);
print '1624: tmp = base(1/3)'; print '1624: tmp = base(1/3)';
vrfy(config("mode") == "frac", '1625: config("mode") == "frac"'); vrfy(config("mode") == "fraction",
'1625: config("mode") == "fraction"');
tmp = base(-10); tmp = base(-10);
print '1626: tmp = base(-10)'; print '1626: tmp = base(-10)';
vrfy(config("mode") == "int", '1627: config("mode") == "int"'); vrfy(config("mode") == "integer",
'1627: config("mode") == "integer"');
tmp = base(10); tmp = base(10);
print '1628: tmp = base(10)'; print '1628: tmp = base(10)';
@@ -1628,7 +1630,8 @@ define test_mode()
tmp = base(1e20); tmp = base(1e20);
print '1630: tmp = base(1e20)'; print '1630: tmp = base(1e20)';
vrfy(config("mode") == "exp", '1631: config("mode") == "exp"'); vrfy(config("mode") == "scientific",
'1631: config("mode") == "scientific"');
tmp = base(16); tmp = base(16);
print '1632: tmp = base(16)'; print '1632: tmp = base(16)';
@@ -2705,11 +2708,11 @@ define test_matobj()
B[0,0] = res(2); B[0,0] = res(2);
print '3106: B[0,0] = res(2)'; print '3106: B[0,0] = res(2)';
B[0,1] = res(3); B[0,1] = res(3);
print '3107: B[0,1] = res(2)'; print '3107: B[0,1] = res(3)';
B[1,0] = res(5); B[1,0] = res(5);
print '3108: B[1,0] = res(2)'; print '3108: B[1,0] = res(5)';
B[1,1] = res(7); B[1,1] = res(7);
print '3109: B[1,1] = res(2)'; print '3109: B[1,1] = res(7)';
print '3110: md = 0'; print '3110: md = 0';
md = 0; md = 0;
vrfy(det(B) == res(-1), '3111: det(B) == res(-1)'); vrfy(det(B) == res(-1), '3111: det(B) == res(-1)');

View File

@@ -44,7 +44,7 @@
*/ */
typedef struct { typedef struct {
char *name; /* name of configuration string */ char *name; /* name of configuration string */
int type; /* type for configuration */ long type; /* type for configuration */
} NAMETYPE; } NAMETYPE;

View File

@@ -410,6 +410,7 @@ config_hash(CONFIG *cfg, QCKHASH val)
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->lib_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);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->ctrl_d);
/* /*
* hash the built up scalar * hash the built up scalar

View File

@@ -1086,9 +1086,8 @@ makenewstring(char *str)
s = stralloc(); s = stralloc();
s->s_str = c; s->s_str = c;
s->s_len = len; s->s_len = len;
while (len-- > 0) memcpy(c, str, len);
*c++ = *str++; c[len] = '\0';
*c = '\0';
return s; return s;
} }
@@ -1097,7 +1096,7 @@ STRING *
stringcopy (STRING *s1) stringcopy (STRING *s1)
{ {
STRING *s; STRING *s;
char *c, *c1; char *c;
long len; long len;
len = s1->s_len; len = s1->s_len;
@@ -1111,10 +1110,8 @@ stringcopy (STRING *s1)
s = stralloc(); s = stralloc();
s->s_len = len; s->s_len = len;
s->s_str = c; s->s_str = c;
c1 = s1->s_str; memcpy(c, s1->s_str, len);
while (len-- > 0) c[len] = '\0';
*c++ = *c1++;
*c = '\0';
return s; return s;
} }

View File

@@ -2827,7 +2827,8 @@ config_print(CONFIG *cfg)
for (cp = configs; cp->name; cp++) { for (cp = configs; cp->name; cp++) {
/* skip if special all or duplicate maxerr value */ /* skip if special all or duplicate maxerr value */
if (cp->type == CONFIG_ALL || strcmp(cp->name, "maxerr") == 0) if (cp->type == CONFIG_ALL || strcmp(cp->name, "maxerr") == 0 ||
strcmp(cp->name, "ctrl-d") == 0)
continue; continue;
/* print tab if allowed */ /* print tab if allowed */

View File

@@ -18,7 +18,7 @@ static char *program;
#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 "10.3.1" /* test number or empty string if no patch */ #define MINOR_PATCH "10.4" /* test number or empty string if no patch */
/* /*
* calc version constants * calc version constants

43
zmath.c
View File

@@ -436,12 +436,10 @@ zsub(ZVALUE z1, ZVALUE z2, ZVALUE *res)
len1 = z1.len; len1 = z1.len;
len2 = z2.len; len2 = z2.len;
if (len1 == len2) { if (len1 == len2) {
h1 = z1.v + len1 - 1; h1 = z1.v + len1;
h2 = z2.v + len2 - 1; h2 = z2.v + len2;
while ((len1 > 0) && ((FULL)*h1 == (FULL)*h2)) { while ((len1 > 0) && ((FULL)*--h1 == (FULL)*--h2)) {
len1--; len1--;
h1--;
h2--;
} }
if (len1 == 0) { if (len1 == 0) {
*res = _zero_; *res = _zero_;
@@ -633,10 +631,12 @@ zdiv(ZVALUE z1, ZVALUE z2, ZVALUE *quo, ZVALUE *rem, long rnd)
A[m + 1] = 0; A[m + 1] = 0;
len = m - n + 1; /* quotient length will be len or len +/- 1 */ len = m - n + 1; /* quotient length will be len or len +/- 1 */
a1 = A + n; /* start of digits for quotient */ a1 = A + n; /* start of digits for quotient */
b0 = B - 1; b0 = B;
p = n; p = n;
while (!*++b0) /* b0: working start for divisor */ while (!*b0) { /* b0: working start for divisor */
p--; ++b0;
--p;
}
if (p == 1) { if (p == 1) {
u = *b0; u = *b0;
if (u == 1) { if (u == 1) {
@@ -893,10 +893,12 @@ zequo(ZVALUE z1, ZVALUE z2, ZVALUE *res)
math_error("Bad call to zequo"); math_error("Bad call to zequo");
/*NOTREACHED*/ /*NOTREACHED*/
} }
B = z2.v - 1; B = z2.v;
o = 0; o = 0;
while (!*++B) while (!*B) {
o++; ++B;
++o;
}
m = z1.len - o; m = z1.len - o;
n = z2.len - o; n = z2.len - o;
len = m - n + 1; /* Maximum length of quotient */ len = m - n + 1; /* Maximum length of quotient */
@@ -1047,12 +1049,12 @@ zdivi(ZVALUE z, long n, ZVALUE *res)
dest.sign = z.sign; dest.sign = z.sign;
dest.len = len; dest.len = len;
dest.v = alloc(len); dest.v = alloc(len);
h1 = z.v + len - 1; h1 = z.v + len;
sd = dest.v + len - 1; sd = dest.v + len;
val = 0; val = 0;
while (len--) { while (len--) {
val = ((val << BASEB) + ((FULL) *h1--)); val = ((val << BASEB) + ((FULL) *--h1));
*sd-- = (HALF)(val / n); *--sd = (HALF)(val / n);
val %= n; val %= n;
} }
zquicktrim(dest); zquicktrim(dest);
@@ -1111,10 +1113,10 @@ zmodi(ZVALUE z, long n)
* The modulus is by a small number, so we can do this quickly. * The modulus is by a small number, so we can do this quickly.
*/ */
len = z.len; len = z.len;
h1 = z.v + len - 1; h1 = z.v + len;
val = 0; val = 0;
while (len--) while (len-- > 0)
val = ((val << BASEB) + ((FULL) *h1--)) % n; val = ((val << BASEB) + ((FULL) *--h1)) % n;
if (val && z.sign) if (val && z.sign)
val = n - val; val = n - val;
return (long)val; return (long)val;
@@ -1784,13 +1786,12 @@ zshiftr(ZVALUE z, long n)
} }
if (n) { if (n) {
len = z.len; len = z.len;
h = z.v + len - 1; h = z.v + len;
mask = 0; mask = 0;
while (len--) { while (len--) {
maskt = (((FULL) *h) << (BASEB - n)) & BASE1; maskt = (((FULL) *--h) << (BASEB - n)) & BASE1;
*h = ((*h >> n) | (HALF)mask); *h = ((*h >> n) | (HALF)mask);
mask = maskt; mask = maskt;
--h;
} }
} }
} }