Compare commits

...

2 Commits

Author SHA1 Message Date
Landon Curt Noll
2c9b160dc5 Release calc version 2.11.0t10.4 2017-05-21 15:38:35 -07:00
Landon Curt Noll
fbd3a79eba Release calc version 2.11.0t10.3.1 2017-05-21 15:38:35 -07:00
43 changed files with 835 additions and 433 deletions

71
CHANGES
View File

@@ -19,9 +19,6 @@ The following are the changes from calc version 2.11.0t10 to date:
The 'unused value ignored' messages now start with Line 999: instead The 'unused value ignored' messages now start with Line 999: instead
of just 999:. of just 999:.
Fixed some typos in the help files as reported by Klaus Alexander
Seistrup <klaus@seistrup.dk>.
Fixed the long standing issue first reported by Saber-C in the Fixed the long standing issue first reported by Saber-C in the
domul() function in zmil.c thanks to a patch by Ernest Bowen domul() function in zmil.c thanks to a patch by Ernest Bowen
<ernie@turing.une.edu.au>. <ernie@turing.une.edu.au>.
@@ -40,6 +37,74 @@ The following are the changes from calc version 2.11.0t10 to date:
Fixed a number of insure warnings as reported by Michel van der List Fixed a number of insure warnings as reported by Michel van der List
<vanderlistmj@sbphrd.com>. <vanderlistmj@sbphrd.com>.
Fixed a number of help file typos discovered by Klaus Alexander
Seistrup <klaus@seistrup.dk>.
Removed REGRESS_CAL as a Makefile variable.
Added calcliblist and calcliblistfmt utility Makefile rules to allow
one to print the list of distribution files that are used (but not
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:
# #
@@ -957,15 +945,6 @@ UTIL_PROGS= align32 fposval have_uid_t longlong have_const \
have_ustat have_getsid have_getpgid \ have_ustat have_getsid have_getpgid \
have_gettime have_getprid ver_calc have_strdup have_gettime have_getprid ver_calc have_strdup
# These files are required by the regress.cal regression test.
#
REGRESS_CAL= ./lib/lucas_chk.cal ./lib/natnumset.cal ./lib/surd.cal \
./lib/test1700.cal ./lib/test2300.cal ./lib/test2600.cal \
./lib/test2700.cal ./lib/test3100.cal ./lib/test3300.cal \
./lib/test3400.cal ./lib/test3500.cal ./lib/test4000.cal \
./lib/test4100.cal ./lib/test4600.cal ./lib/test5100.cal \
./lib/test5200.cal
# The complete list of makefile vars passed down to custom/Makefile. # The complete list of makefile vars passed down to custom/Makefile.
# #
CUSTOM_PASSDOWN= Q="${Q}" \ CUSTOM_PASSDOWN= Q="${Q}" \
@@ -1057,7 +1036,12 @@ C_SRC= ${LIBSRC} ${CALCSRC} ${UTIL_C_SRC}
# These files are found (but not built) in the distribution # These files are found (but not built) in the distribution
# #
DISTLIST= ${C_SRC} ${H_SRC} ${MAKE_FILE} BUGS CHANGES LIBRARY README \ DISTLIST= ${C_SRC} ${H_SRC} ${MAKE_FILE} BUGS CHANGES LIBRARY README \
calc.man lint.sed HOWTO.INSTALL ${UTIL_MISC_SRC} calc.man lint.sed HOWTO.INSTALL ${UTIL_MISC_SRC}
# These files are used to make (but not built) a calc .a library
#
CALCLIBLIST= ${LIBSRC} ${UTIL_C_SRC} ${LIB_H_SRC} ${MAKE_FILE} \
${UTIL_MISC_SRC} BUGS CHANGES LIBRARY
# complete list of .o files # complete list of .o files
# #
@@ -1074,7 +1058,7 @@ PROGS= calc ${UTIL_PROGS}
# complete list of targets # complete list of targets
# #
TARGETS= ${CALC_LIBS} custom/.all calc sample/sample \ TARGETS= ${CALC_LIBS} custom/.all calc sample/sample \
lib/.all help/.all help/builtin calc.1 lib/.all help/.all help/builtin calc.1
### ###
@@ -1098,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
## ##
# #
@@ -1163,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
@@ -2559,17 +2537,29 @@ distlist: ${DISTLIST}
${Q}(for i in ${DISTLIST}; do \ ${Q}(for i in ${DISTLIST}; do \
echo $$i; \ echo $$i; \
done; \ done; \
(cd help; ${MAKE} ${HELP_PASSDOWN} distlist); \ (cd help; ${MAKE} ${HELP_PASSDOWN} $@); \
(cd lib; ${MAKE} ${LIB_PASSDOWN} distlist); \ (cd lib; ${MAKE} ${LIB_PASSDOWN} $@); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} distlist); \ (cd custom; ${MAKE} ${CUSTOM_PASSDOWN} $@); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} distlist)) | ${SORT} (cd sample; ${MAKE} ${SAMPLE_PASSDOWN} $@)) | ${SORT}
distdir: distdir:
${Q}(echo .; \ ${Q}(echo .; \
(cd help; ${MAKE} ${HELP_PASSDOWN} distdir); \ (cd help; ${MAKE} ${HELP_PASSDOWN} $@); \
(cd lib; ${MAKE} ${LIB_PASSDOWN} distdir); \ (cd lib; ${MAKE} ${LIB_PASSDOWN} $@); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} distdir); \ (cd custom; ${MAKE} ${CUSTOM_PASSDOWN} $@); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} distdir)) | ${SORT} (cd sample; ${MAKE} ${SAMPLE_PASSDOWN} $@)) | ${SORT}
calcliblist:
${Q}(for i in ${CALCLIBLIST}; do \
echo $$i; \
done; \
(cd help; ${MAKE} ${HELP_PASSDOWN} $@); \
(cd lib; ${MAKE} ${LIB_PASSDOWN} $@); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} $@); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} $@)) | ${SORT}
calcliblistfmt:
${Q}${MAKE} calcliblist | ${FMT} -64 | ${SED} -e 's/^/ /'
## ##
# #
@@ -2583,10 +2573,10 @@ distdir:
# #
## ##
check: all ./lib/regress.cal ${REGRESS_CAL} check: all ./lib/regress.cal
${CALC_ENV} ./calc -d -q read regress ${CALC_ENV} ./calc -d -q read regress
chk: ./lib/regress.cal ${REGRESS_CAL} chk: ./lib/regress.cal
${V} echo '=-=-=-=-= start of $@ rule =-=-=-=-=' ${V} echo '=-=-=-=-= start of $@ rule =-=-=-=-='
${CALC_ENV} ./calc -d -q read regress 2>&1 | ${AWK} -f check.awk ${CALC_ENV} ./calc -d -q read regress 2>&1 | ${AWK} -f check.awk
${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-=' ${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-='
@@ -2644,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 ""
@@ -2690,7 +2679,6 @@ env:
@echo "UTIL_TMP=${UTIL_TMP}"; echo "" @echo "UTIL_TMP=${UTIL_TMP}"; echo ""
@echo "UTIL_PROGS=${UTIL_PROGS}"; echo "" @echo "UTIL_PROGS=${UTIL_PROGS}"; echo ""
@echo "LIB_H_SRC=${LIB_H_SRC}"; echo "" @echo "LIB_H_SRC=${LIB_H_SRC}"; echo ""
@echo "REGRESS_CAL=${REGRESS_CAL}"; echo ""
@echo "CUSTOM_PASSDOWN=${CUSTOM_PASSDOWN}"; echo "" @echo "CUSTOM_PASSDOWN=${CUSTOM_PASSDOWN}"; echo ""
@echo "SAMPLE_PASSDOWN=${SAMPLE_PASSDOWN}"; echo "" @echo "SAMPLE_PASSDOWN=${SAMPLE_PASSDOWN}"; echo ""
@echo "HELP_PASSDOWN=${HELP_PASSDOWN}"; echo "" @echo "HELP_PASSDOWN=${HELP_PASSDOWN}"; echo ""
@@ -2957,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 =-=-=-=-='
## ##

85
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"
if (fp == NULL) "-----\t------ \t---- \t------\n");
continue; else
if (count++ == 0) { math_str("Name\tArguments\n"
printf("Name Arguments\n---- ---------\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)
continue;
count++;
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) { if (conf->lib_debug & LIBDBG_FUNC_INFO) {
printf("\nNumber: %ld\n", count); 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.

319
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:
* name mode name * set the NAMESET array of name/int pairs
* 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

View File

@@ -285,6 +285,10 @@ H_SRC= ${CUSTOM_H_SRC}
DISTLIST= ${CUSTCALC_SRC} ${CUSTOM_CALC_FILES} ${CUSTOM_HELP} \ DISTLIST= ${CUSTCALC_SRC} ${CUSTOM_CALC_FILES} ${CUSTOM_HELP} \
${INSTALL_H_SRC} CUSTOM_CAL HOW_TO_ADD ${MAKE_FILE} ${INSTALL_H_SRC} CUSTOM_CAL HOW_TO_ADD ${MAKE_FILE}
# These files are used to make (but not built) a calc .a library
#
CALCLIBLIST= ${CUSTCALC_SRC} ${INSTALL_H_SRC} ${MAKE_FILE} HOW_TO_ADD
# complete list of targets # complete list of targets
# #
TARGETS= libcustcalc.a ${CUSTCALC_OBJ} TARGETS= libcustcalc.a ${CUSTCALC_OBJ}
@@ -352,6 +356,13 @@ distlist: ${DISTLIST}
distdir: distdir:
${Q}echo custom ${Q}echo custom
calcliblist: ${CALCLIBLIST}
${Q}for i in ${CALCLIBLIST} /dev/null; do \
if [ X"$$i" != X"/dev/null" ]; then \
echo custom/$$i; \
fi; \
done
## ##
# #
# Home grown make dependency rules. Your system make not support # Home grown make dependency rules. Your system make not support

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
@@ -147,6 +147,10 @@ DISTLIST= ${STD_HELP_FILES} ${DETAIL_HELP} ${MAKE_FILE} \
obj.file builtin.top builtin.end funclist.sed \ obj.file builtin.top builtin.end funclist.sed \
errorcodes.hdr errorcodes.sed errorcodes.hdr errorcodes.sed
# These files are used to make (but not built) a calc .a library
#
CALCLIBLIST=
all: ${FULL_HELP_FILES} full ${DETAIL_HELP} ${DETAIL_CLONE} \ all: ${FULL_HELP_FILES} full ${DETAIL_HELP} ${DETAIL_CLONE} \
${SINGULAR_FILES} calc .all ${SINGULAR_FILES} calc .all
@@ -171,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 $@
@@ -395,6 +387,13 @@ distlist: ${DISTLIST}
distdir: distdir:
${Q}echo help ${Q}echo help
calcliblist:
${Q}for i in ${CALCLIBLIST} /dev/null; do \
if [ X"$$i" != X"/dev/null" ]; then \
echo help/$$i; \
fi; \
done
# 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
# ignore this rule. # ignore this rule.

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

@@ -74,7 +74,7 @@ DESCRIPTION
chunksize is created by C = blk(B, newlen, newchunk), only the first chunksize is created by C = blk(B, newlen, newchunk), only the first
min(len, newlen) octets being copied from B; later octets are min(len, newlen) octets being copied from B; later octets are
assigned zero value. If omitted, newlen and newchunk default to assigned zero value. If omitted, newlen and newchunk default to
the current datalen and chunk-size for B. The curent datalen, the current datalen and chunk-size for B. The current datalen,
chunksize and number of allocated octets for B may be changed by: chunksize and number of allocated octets for B may be changed by:
B = blk(B, newlen, newchunk). B = blk(B, newlen, newchunk).

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

@@ -20,7 +20,7 @@ DESCRIPTION
Standard input, standard output and standard error are always opened Standard input, standard output and standard error are always opened
and cannot be closed. and cannot be closed.
The truth value of an closed file is FALSE. The truth value of a closed file is FALSE.
The fclose function returns the numeric value of errno if The fclose function returns the numeric value of errno if
there had been an error using the file, or the null value if there had been an error using the file, or the null value if

View File

@@ -23,7 +23,7 @@ EXAMPLE
0 0
LIMITS LIMITS
fd must be associaed with an open file fd must be associated with an open file
LIBRARY LIBRARY
none none

View File

@@ -10,7 +10,7 @@ TYPES
return nil return nil
DESCRIPTION DESCRIPTION
This function forces and buffered output to the file associated with fd. This function forces a buffered output to the file associated with fd.
EXAMPLE EXAMPLE
> fd = fopen("/tmp/file", "w") > fd = fopen("/tmp/file", "w")
@@ -18,7 +18,7 @@ EXAMPLE
> fflush(fd) > fflush(fd)
LIMITS LIMITS
fd must be associaed with an open file fd must be associated with an open file
LIBRARY LIBRARY
none none

View File

@@ -25,7 +25,7 @@ EXAMPLE
"c" "c"
LIMITS LIMITS
fd must be associaed with an open file fd must be associated with an open file
LIBRARY LIBRARY
none none

View File

@@ -41,7 +41,7 @@ EXAMPLE
123 123
LIMITS LIMITS
fd must be associaed with an open file fd must be associated with an open file
LIBRARY LIBRARY
none none

View File

@@ -14,7 +14,7 @@ DESCRIPTION
the open file associated with fd. Unlike fgetline, the trailing the open file associated with fd. Unlike fgetline, the trailing
newline is included in the return string. newline is included in the return string.
If a line is read, is returned, otherwise (EOF or ERROR) nil is returned. If a line is read, it is returned, otherwise (EOF or ERROR) nil is returned.
EXAMPLE EXAMPLE
> fd = fopen("/tmp/newfile", "w") > fd = fopen("/tmp/newfile", "w")
@@ -30,7 +30,7 @@ EXAMPLE
"chongo was here" "chongo was here"
LIMITS LIMITS
fd must be associaed with an open file fd must be associated with an open file
LIBRARY LIBRARY
none none

View File

@@ -14,7 +14,7 @@ DESCRIPTION
If the stream cannot be read, an error value is returned. If the stream cannot be read, an error value is returned.
Otherwise the function retrurns the string of characters from the Otherwise the function returns the string of characters from the
current file position to the first null character ('\0') (the file current file position to the first null character ('\0') (the file
position for further reading then being immediately after the '\0'), position for further reading then being immediately after the '\0'),
or if no null character is encountered, the string of characters to or if no null character is encountered, the string of characters to

View File

@@ -10,7 +10,7 @@ TYPES
return files, int or null return files, int or null
DESCRIPTION DESCRIPTION
This function, then given the argument fnum, will use it as an This function, when given the argument fnum, will use it as an
index into an internal table of open file and return a file value. index into an internal table of open file and return a file value.
If that entry in the table is not in use, then the null value is If that entry in the table is not in use, then the null value is
returned instead. When no args are given, the maximum number of returned instead. When no args are given, the maximum number of

View File

@@ -13,7 +13,7 @@ TYPES
DESCRIPTION DESCRIPTION
This function opens the file named filename. A file can be This function opens the file named filename. A file can be
opened for either reading, writing, or appending. The mode opened for either reading, writing, or appending. The mode
is controlled by the mode flag as folllows: is controlled by the mode flag as follows:
"r" reading "r" reading
"w" writing "w" writing

View File

@@ -11,7 +11,7 @@ TYPES
return null value return null value
DESCRIPTION DESCRIPTION
In forall(x,y), y is to the the name of a function; that function In forall(x,y), y is the name of a function; that function
is performed in succession for all elements of x. This is similar is performed in succession for all elements of x. This is similar
to modify(x, y) but x is not changed. to modify(x, y) but x is not changed.

View File

@@ -22,7 +22,7 @@ EXAMPLE
"c" "c"
LIMITS LIMITS
fd must be associaed with an open file fd must be associated with an open file
LIBRARY LIBRARY
none none

View File

@@ -1,5 +1,5 @@
NAME NAME
freeglobals - free memory used for values of global variabls freeglobals - free memory used for values of global variables
SYNOPSIS SYNOPSIS
freeglobals() freeglobals()

View File

@@ -16,7 +16,7 @@ DESCRIPTION
Otherwise, until the terminating null character of fmt is encountered Otherwise, until the terminating null character of fmt is encountered
or end-of-file for fs is reached, characters other than '%' and white or end-of-file for fs is reached, characters other than '%' and white
space are read from fmt and compared with the corresponding chracters space are read from fmt and compared with the corresponding characters
read from fs. If the characters match, the reading continues. If they read from fs. If the characters match, the reading continues. If they
do not match, an integer value is returned and the file position for do not match, an integer value is returned and the file position for
fs is the position of the non-matching character. If white space fs is the position of the non-matching character. If white space
@@ -72,7 +72,7 @@ DESCRIPTION
might be taken to suggest a number like +2345; 'r' might suggest might be taken to suggest a number like +2345; 'r' might suggest
a representation like -27/49; 'e' might suggest a representation like a representation like -27/49; 'e' might suggest a representation like
1.24e-7; 'f' might suggest a representation like 27.145. However, there 1.24e-7; 'f' might suggest a representation like 27.145. However, there
is no test that the the result conforms to the specifier. Whatever is no test that the result conforms to the specifier. Whatever
the specifier in these cases, the result depends on the characters read the specifier in these cases, the result depends on the characters read
until a space or other exceptional character is read. The until a space or other exceptional character is read. The
characters read may include one or more occurrences of +, -, * as characters read may include one or more occurrences of +, -, * as

View File

@@ -20,7 +20,7 @@ EXAMPLE
784 784
LIMITS LIMITS
fd must be associaed with an open file fd must be associated with an open file
LIBRARY LIBRARY
none none

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 \
@@ -51,6 +51,10 @@ CALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.cal \
# #
DISTLIST= ${CALC_FILES} ${MAKE_FILE} DISTLIST= ${CALC_FILES} ${MAKE_FILE}
# These files are used to make (but not built) a calc .a library
#
CALCLIBLIST=
all: ${CALC_FILES} ${MAKE_FILE} .all all: ${CALC_FILES} ${MAKE_FILE} .all
# used by the upper level Makefile to determine of we have done all # used by the upper level Makefile to determine of we have done all
@@ -80,6 +84,13 @@ distlist: ${DISTLIST}
distdir: distdir:
${Q}echo lib ${Q}echo lib
calcliblist:
${Q}for i in ${CALCLIBLIST} /dev/null; do \
if [ X"$$i" != X"/dev/null" ]; then \
echo lib/$$i; \
fi; \
done
clean: clean:
clobber: clobber:

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

@@ -263,6 +263,10 @@ H_SRC= ${SAMPLE_H_SRC}
# #
DISTLIST= ${C_SRC} ${H_SRC} ${MAKE_FILE} README_SAMPLE DISTLIST= ${C_SRC} ${H_SRC} ${MAKE_FILE} README_SAMPLE
# These files are used to make (but not built) a calc .a library
#
CALCLIBLIST= ${C_SRC} ${H_SRC} ${MAKE_FILE} README_SAMPLE
# complete list of targets # complete list of targets
# #
TARGETS= many_random test_random TARGETS= many_random test_random
@@ -327,6 +331,13 @@ distlist: ${DISTLIST}
distdir: distdir:
${Q}echo sample ${Q}echo sample
calcliblist:
${Q}for i in ${CALCLIBLIST} /dev/null; do \
if [ X"$$i" != X"/dev/null" ]; then \
echo sample/$$i; \
fi; \
done
## ##
# #
# Home grown make dependency rules. Your system make not support # Home grown make dependency rules. Your system make not support

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" /* 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;
} }
} }
} }