Compare commits

..

12 Commits

Author SHA1 Message Date
Landon Curt Noll
9204d2fb8c Release calc version 2.11.0t7.2 2017-05-21 15:38:28 -07:00
Landon Curt Noll
35982c7cc8 Release calc version 2.11.0t7.1 2017-05-21 15:38:28 -07:00
Landon Curt Noll
4c0f2691e9 Release calc version 2.11.0t7 2017-05-21 15:38:28 -07:00
Landon Curt Noll
0d37ccb019 Release calc version 2.11.0t6.3 2017-05-21 15:38:28 -07:00
Landon Curt Noll
d7d31e9246 Release calc version 2.11.0t6.2 2017-05-21 15:38:28 -07:00
Landon Curt Noll
2dc364ee9f Release calc version 2.11.0t6.1 2017-05-21 15:38:28 -07:00
Landon Curt Noll
b54d8fc510 Release calc version 2.11.0t6 2017-05-21 15:38:27 -07:00
Landon Curt Noll
8cabbd6fb4 Release calc version 2.11.0t5.2 2017-05-21 15:38:27 -07:00
Landon Curt Noll
ea64a95b90 Release calc version 2.11.0t5.1 2017-05-21 15:38:27 -07:00
Landon Curt Noll
f60cbd24b2 Release calc version 2.11.0t5 2017-05-21 15:38:27 -07:00
Landon Curt Noll
97e9429000 Release calc version 2.11.0t4 2017-05-21 15:38:27 -07:00
Landon Curt Noll
1ce630ac19 Release calc version 2.11.0t3 2017-05-21 15:38:26 -07:00
117 changed files with 2653 additions and 1408 deletions

163
BUGS
View File

@@ -1,8 +1,8 @@
If you notice something wrong, strange or broken, try rereading: If you notice something wrong, strange or broken, try rereading:
README.FIRST README.FIRST
README HOWTO.INSTALL
BUGS (in particular the bottom problems or mis-features section) BUGS (this file)
If that does not help, cd to the calc source directory and try: If that does not help, cd to the calc source directory and try:
@@ -18,13 +18,13 @@ If it does not, then something is really broken!
If you made and modifications to calc beyond the simple Makefile If you made and modifications to calc beyond the simple Makefile
configuration, try backing them out and see if things get better. configuration, try backing them out and see if things get better.
Check to see if the version of calc you are using is current. Calc To be sure that your version of calc is up to date, check out:
distributions may be obtained from the official calc repository:
ftp://ftp.uu.net/pub/calc http://reality.sgi.com/chongo/calc/calc-download.html
If you are an alpha or beta tester, you may have a special pre-released The calc web site is located at:
version that is more advanced than what is in the ftp archive.
http://reality.sgi.com/chongo/calc
=-= =-=
@@ -46,6 +46,8 @@ When you send your report, please include the following information:
* the type of compiler you were using * the type of compiler you were using
* any compiler warnings or erros that you saw
* cd to the calc source directory, and type: * cd to the calc source directory, and type:
make debug > debug.out 2>&1 (sh, ksh, bash users) make debug > debug.out 2>&1 (sh, ksh, bash users)
@@ -57,22 +59,8 @@ Stack traces from core dumps are useful to send as well.
=-= =-=
The official calc repository is located in: Send any comments, compiler warning messages, suggestions and most
importantly, fixes (in the form of a context diff patch) to:
ftp://ftp.uu.net/pub/calc
If you don't have ftp access to that site, or if your version is more
recent than what has been released to the ftp archive, you may, as a
last resort, send EMail to:
chongo@toad.com
Indicate the version you have and that you would like a more up to date version.
=-=
Send any comments, suggestions and most importantly, fixes (in the form
of a context diff patch) to:
calc-tester@postofc.corp.sgi.com calc-tester@postofc.corp.sgi.com
@@ -89,132 +77,3 @@ Known problems or mis-features:
* There is some places in the source with obscure variable names * There is some places in the source with obscure variable names
and not much in the way of comments. We need some major cleanup and not much in the way of comments. We need some major cleanup
and documentation. and documentation.
* On a Dec Alpha, make check for version 2.11.0t1 core dumps:
From vandermj@molbio.sbphrd.com Fri Sep 24 06:15:28 1999
Subject: Re: calc version 2.11.0t1
Date: Fri, 24 Sep 1999 09:15:02 -0400
It dies as follows:
...
1802: a = surd(2,3)
1803: a == surd(2,3)
1804: surd_value(a) == 2+3i
Segmentation fault
dbx shows:
signal Segmentation fault at [objcall:155 +0xc,0x1200507b4] index = oap->actions[action];
(dbx) where
> 0 objcall(action = 14, v1 = 0x1400203d0, v2 = 0x1400203e0, v3 = (nil)) ["obj.c":155, 0x1200507b4]
1 comparevalue(v1 = 0x1400203d0, v2 = 0x1400203e0) ["value.c":2329, 0x12007f250]
2 o_eq() ["opcodes.c":2659, 0x12003728c]
3 calculate(fp = 0x14007fce0) ["opcodes.c":3614, 0x12003942c]
4 o_usercall(fp = 0x14007fce0, index = 39, argcount = 0) ["opcodes.c":2602, 0x120037080]
5 calculate(fp = 0x14003bfa0) ["opcodes.c":3622, 0x120039488]
6 evaluate(nestflag = 14) ["codegen.c":210, 0x120028768]
7 getcommands(toplevel = 536864560) ["codegen.c":158, 0x1200285bc]
8 getcommands(toplevel = 536864560) ["codegen.c":122, 0x1200284dc]
9 main() ["calc.c":279, 0x12001f61c]
However On 25-Sep-99 9:18, Ernest Bowen wrote:
Last night I downloaded 2.11.0t1 and without changing Makefile
or anything else did a make and make check. Absolutely no
reported errors or warnings and the check "passed all tests".
The machine I'm using is a Dec 20 alpha running Digitial
UNIX V4.0B (Rev 564).
Any ideas on how to reconcile these different results?
* On Sun SPARCstation running Solaris 2.5.1 compiling with
cc version 4.0 with -Xc option 'make check' fails on the hash
functions. However when compiled with gcc everything seems to
work just fine.
From: "Dr.D.J.Picton" <dave@aps5.ph.bham.ac.uk>
Date: Fri, 8 May 1998 10:54:43 +0100
Platform: Sun SPARCstation
Operating system: Solaris 2.5.1
Compiler: cc version 4.0 with -Xc option.
The code compiled OK but the sha() and sha1() functions give errors with
make check. These functions clearly are broken. For example,
sha(sha()) gives
0xea19f96cdd568ad1084a17acc6103d92c0ef7708 not
0xf96cea198ad1dd5617ac084a3d92c6107708c0ef
Interestingly, the consistency checks work OK e.g.
>B = blk() = {"a", "b", "c"};
>sha(B) == sha("abc");
1
**** Non-true result (0): 7108: sha(sha()) ==
0xf96cea198ad1dd5617ac084a3d92c6107708c0ef
**** Non-true result (0): 7109:
sha(sha("a"))==0x37f297772fae4cb1ba39b6cf9cf0381180bd62f2
**** Non-true result (0): 7110:
sha(sha("ab"))==0x488373d362684af3d3f7a6a408b59dfe85419e09
**** Non-true result (0): 7111:
sha(sha("abc"))==0x0164b8a914cd2a5e74c4f7ff082c4d97f1edf880
**** Non-true result (0): 7112:
sha(sha("abcd"))==0x082c73b06f71185d840fb4b28eb3abade67714bc
**** Non-true result (0): 7113:
sha(sha("abcde"))==0xd624e34951bb800f0acae773001df8cffe781ba8
**** Non-true result (0): 7114:
sha(sha("abcdef"))==0x2a589f7750598dc0ea0a608719e04327f609279a
**** Non-true result (0): 7115:
sha(sha("abcdefg"))==0x5bdf01f9298e9d19d3f8d15520fd74eed600b497
**** Non-true result (0): 7116:
sha(sha("abcdefgh"))==0x734ba8b31975d0dbae4d6e249f4e8da270796c94
**** Non-true result (0): 7117: sha(sha(1)) ==
0x864c8d09e828c7c31d62693736a5a9302c282777
**** Non-true result (0): 7118: sha(sha(2)) ==
0x2c0b59c512cb20fad6bb0883b69c9f5a46545808
**** Non-true result (0): 7119:
sha(sha(22/7)==0x7ddb7f8a7e9d70757f157744fddea7a6c6a6bcc6
**** Non-true result (0): 7120:
sha(sha(isqrt(2e1000)==0x6db8d9cf0b018b8f9cbbf5aa1edb8066d19e1bb0
7121: sha("x", "y", "z") == sha("xyz")
**** Non-true result (0): 7122: sha(sha("this is", 7^19-8, ..., "hash")) ==
0x21e4...
7123: z = sha(list(1,2,3), "curds and whey", 2^21701-1, pi());
**** Non-true result (0): 7124: sha(z) ==
0x36dcca3e51865c30a2cf738023cda446f1368340
**** Non-true result (0): 7207: sha1(sha1()) ==
0xda39a3ee5e6b4b0d3255bfef95601890afd80709
7208: sha1("x", "y", "z") == sha1("xyz")
**** Non-true result (0): 7209: sha1(sha1("this is",7^19-8,"a
composit",3i+4.5,"hash")) == ...
7210: z = sha1(list(1,2,3), "curds and whey", 2^21701-1, pi());
**** Non-true result (0): 7211: sha1(z) ==
0xc19e7317675dbf71e293b4c41e117169e9da5b6f
**** Non-true result (0): 7217:
sha1(sha1("a"))==0x86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
**** Non-true result (0): 7218:
sha1(sha1("ab"))==0xda23614e02469a0d7c7bd1bdab5c9c474b1904dc
**** Non-true result (0): 7219:
sha1(sha1("abc"))==0xa9993e364706816aba3e25717850c26c9cd0d89d
**** Non-true result (0): 7220:
sha1(sha1("abcd"))==0x81fe8bfe87576c3ecb22426f8e57847382917acf
**** Non-true result (0): 7221:
sha1(sha1("abcde"))==0x03de6c570bfe24bfc328ccd7ca46b76eadaf4334
**** Non-true result (0): 7222:
sha1(sha1("abcdef"))==0x1f8ac10f23c5b5bc1167bda84b833e5c057a77d2
**** Non-true result (0): 7223:
sha1(sha1("abcdefg"))==0x2fb5e13419fc89246865e7a324f476ec624e8740
**** Non-true result (0): 7224:
sha1(sha1("abcdefgh"))==0x425af12a0743502b322e93a015bcf868e324d56a
**** Non-true result (0): 7225:
sha1(sha1(1))==0x53dd4e1734ad47d45e41c23e4ce42d7f1f98c1e8
**** Non-true result (0): 7226:
sha1(sha1(22/7))==0xf8e2510f85f7b9bf088b321188e9f70620f44246
**** Non-true result (0): 7227:
sha1(sha1(isqrt(2e1000)))==0x6852a1365c51050c3d039e3c5d9cf29c12283ef4

301
CHANGES
View File

@@ -1,15 +1,136 @@
Following is the change from calc version 2.11.0t1 to date: Following is the change from calc version 2.11.0t7 to date:
Removed the makefile symbol MAIN. Now forcing all funcions to correctly Calc has some new command line flags / command line meaning:
be reclared main. To passify some old broken compilers, a return 0; (Thanks goes to Ernest Bowen <ernie@turing.une.edu.au>)
-i Go into interactive mode if possible.
-c Continue reading command lines even after an execution
error has caused the abandonment of a line
To understand the -i and -c effects, consider the following
file (call it myfile.cal) which has deliberate errors in it:
print 1;
mat A[1] = {2,3};
print 2;
epsilon(-1);
print 3;
calc read myfile
Reports an error on the 2nd line and exits; prints 1 only.
calc -c read myfile
Report errors on the 2nd and 4th lines and exits; prints 1,2 and 3.
calc -i read myfile
Report errors on the 2nd and gives you a prompt; prints 1 only.
calc -i -c read myfile
Report errors on the 2nd and 4th and gives you a prompt;
prints 1, 2 and 3.
cat myfile | calc
Reports an error on the 2nd line and exits; prints 1 only.
cat myfile | calc -c
Report errors on the 2nd and 4th lines and exits; prints 1,2 and 3.
Note that continuation refers to command lines, not to statements. So:
calc -c 'print "start"; mat A[1] = {2,3}; print "end";'
since it contains no newline, the whole string is compiled,
but execution is abandoned when the error is encountered and
the string ``end'' is not printed.
You can use your shell to supply newlines in your command line
arguments. For example in sh, ksh, bash:
calc -c 'print "start";
mat A[1] = {2,3};
print "end";'
will print both ``start'' and ``end''. C-shell users can do:
calc -c 'print "start"; \
mat A[1] = {2,3}; \
print "end";'
however sh, ksh, bash will not see ``end'' printed because their
shell will remove the internal newlines.
Added display(n) builtin which does almost the same as config("display",n)
except that rather than causing an execution with an out-of-range or
bad-type argument type, it simply writes a message to stderr. This
also now happens to the errmax() builtin.
Added qtime.cal to the standard calc library.
Added another command line flag to calc:
-d Disable display of the opening title and config("lib_debug",0)
The command:
calc 'read qtime; qtime(2)'
will output something like:
qtime(utc_hr_offset) defined
It's nearly ten past six.
whereas:
calc -d 'read qtime; qtime(2)'
will just say:
It's nearly ten past six.
A call of errmax(-1) will prevent errcount from aborting calc.
Add the function stoponerror(n) which, as the name implies, controls
if calc stop on an error based on the value of n:
n > 0 stop on error even if -c was given on the command line
n == 0 if -c, continue, without -c, stop
n < 0 continue on error, even if -c was given on the command line
Calc compilation now stops at the first scanerror.
Restored the feature where -p disables the printing of leading tabs
as of config("tab",0) had been executed. So using calc in a pipe:
calc -p 2+17 | whey
will write '19' instead of '\t17' to the whey command.
Updated calc man page and help/usage file to reflect recent
command line changes.
Converted start_done into a general calc run state enum called
run_state within the calc source.
Misc calc man page fixes.
Following is the change from calc version 2.11.0t1 to 2.11.0t6.3:
Removed the makefile symbol MAIN. Now forcing all functions to correctly
be declared main. To satisfy some old broken compilers, a return 0;
(instead of an exit(0);) is used at the end of main(). (instead of an exit(0);) is used at the end of main().
A few of files that were added to calc used 4 character indentation A few of files that were added to calc used 4 character indentation
whereas most of calc uses 8 character indentation. These imported whereas most of calc uses 8 character indentation. These imported
sources have been changed to conform better with the calc style. sources have been changed to conform better with the calc style.
Fixed misc compile warnings.
Added the program calc_errno.c and the Makefile symbol ERRNO_DECL. Added the program calc_errno.c and the Makefile symbol ERRNO_DECL.
If ERRNO_DECL is empty, calc_errno.c will try various ways to If ERRNO_DECL is empty, calc_errno.c will try various ways to
declare errno, sys_errlist and sys_nerr. On success or when declare errno, sys_errlist and sys_nerr. On success or when
@@ -21,6 +142,176 @@ Following is the change from calc version 2.11.0t1 to date:
The func.c file now includes the constructed header file calc_errno.h The func.c file now includes the constructed header file calc_errno.h
to ensure that errno, sys_errlist and sys_nerr are declared correctly. to ensure that errno, sys_errlist and sys_nerr are declared correctly.
Changed check.awk to be more 'old awk' friendly.
Made some of the source a little more ++ friendly. We are NOT
porting calc to C++! We will NOT support C++ compilation of calc.
Calc will written ANSI C. We just compiled with a suggestion from
Love-Jensen, John <jlove-jensen@globalmt.com> to make calc's version
of C a little more to C++ compilers. We are simply avoiding symbols
such as new or try for example.
Renamed README to README.OLD. Renamed README.FIRST to README.
Updated README, lib/README and BUGS to reflect new URLs and addresses.
Added a HOWTO.INSTALL file.
Reordered cc Makefile variable sets in the main Makefile.
Fixed a bug in hnrmod() and applied a fix that was reported by Ernest
Bowen <ernie@turing.une.edu.au>. Added regression tests 1103 to
1112 to confirm the fix.
Fixed a bug in version.c related to MINOR_PATCHs in both the
empty and non-empty MINOR_PATCH cases.
Fixed malloc and bad storage issues reported by Michel van der List
<vanderlistmj@sbphrd.com>.
Fixed some problems related to path processing while opening files.
Under extreme cases, an excessively long filename or CALCPATH value
could create problems. Placed guards in opensearchfile() function
in input.c to catch these cases.
Fixed cases were malloc failures were silently ignored in input.c.
Eliminated the PATHSIZE limit and the PATHSIZE symbol.
Added MAX_CALCRC to limit the length of the $CALCRC environment
variable to 1024 chars.
Fixed the magic number relating to the initial number of constants
declared by initconstants(). It is now related to the length
of the initnumbs[] NUMBER array.
Added a 'Dec Alpha / Compaq Tru64 cc (non-gnu) compiler set'
section to the main Makefile.
Fixed a string handling bug discovered by Dr.D.J.Picton
<dave@aps5.ph.bham.ac.uk> in the custom demo code.
Fixed a bug in the hnrmod() builtin that was discovered by
Ernest Bowen <ernie@neumann.une.edu.au>.
Added FORCE_STDC symbol. When defined it will force __STDC__ like
conditions. Thus for compilers with as the Solaris cc compiler
that are ANSI-like but still define __STDC__ as 0, one can use
-DFORCE_STDC and make use of ANSI-like features.
Removed the CCSHS symbol from the Makefile. The shs.c and shs1.c
files are now compiled with full ${CFLAGS}.
The custom.c file is now compiled with full ${CFLAGS}.
Rewrote command line / argument processing code. Calc is now
using getopt(3) argument processing.
Fixed a memory leak related to converting strings to numbers
in the str2q() function in qio.c.
Fixed a problem with reading uninitialized memory in the
v_subtype of a VALUE in the copyvalue() function in value.c.
Fixed problems in func.c where temporary VALUEs were not
having their v_type elements initialized.
Fixed a memory leak in qpi() in qtrans.c.
Fixed a memory leak in math_getdivertedio() in zio.c.
Fixed a problem with points going beyond the end of allocated
memory in addstring() in string.c.
Fixed a memory leak in zgcdrem(), f_putenv(), zlog() and
zlog10() in zfunc.c.
Fixed a memory leak in zdiv() and zshift() in zmath.c.
Fixed memory leaks in zsrand() in zrand.c.
Fixed a memory leak in zsrandom1() in zrandom.c. Fixed memory
leaks associated with replacing the internal random state with
another random state.
Added seed() builtin to return a 64 bit seed for a
pseudo-random generator.
Added functionality from Ernest Bowen <ernie@turing.une.edu.au> to
permit nested "= {...}" assignments for lists as well as matrices
and objects. Now one can have a list, matrix or object, some of
whose elements are lists, matrices or objects, to any depth of
recursion, and assign values to any number of particular elements
by an appropriate "initialization" expression. For example:
A = mat[2] = {list(1,2), list(3,4,list(5,6))};
and then assign values to the 6 number elements by:
A = {{7,8}, {9,10,{11,12}}};
Closed files that were previously left open from test4600.cal
as executed by regress.cal and from opening /dev/null by
regress.cal itself.
Fixed memory leaks from f_strprintf() and f_putenv() in func.c.
The regress.cal test suite calls freeredc(), freestatics() and
freeglobals() at the end of the test suite to free storage
consumed during the regression.
Added custom function custom("pzasusb8", n) and lib/pzasusb8.cal based on
Ernest Bowen's diagnostic patch.
Thanks to the efforts of Ernest Bowen <ernie@neumann.une.edu.au> and
Dr.D.J.Picton <dave@aps5.ph.bham.ac.uk>, a nasty endian-ness bug
in the sha and sha1 hash functions that showed up on machines such
as the Sparc was fixed.
Added functionality from Ernest Bowen <ernie@turing.une.edu.au>
to give arguments as well as function names after definitions when
config("lib_debug") >= 0.
Removed if (config("lib_debug") >= 0) { ... } the ends of most
of the calc library scripts because it was redundant with the
new config("lib_debug") >= 0 functionality. Some of the calc
library still has a partial section because some useful
additional information was being printed:
chrem.cal deg.cal lucas_tbl.cal randrun.cal
mfactor.cal mod.cal poly.cal seedrandom.cal
surd.cal varargs.cal
Fixed ellip.cal so that its defined function does not conflict with
the factor() builtin function.
Fixed mod.cal so that a defined function does not conflict with
the mod() builtin function.
The regression test suite now reads in most calc libs. A few
libs are not read because they, by design, produce output
when read even when config("lib_debug") is set to -1.
Increased the maximum number of object types that one can define
from 10 to 128.
Added a patch from Ernest Bowen <ernie@turing.une.edu.au>
to correctly hash a V_STR value-type that has an \0 byte
inside it.
A patch from Ernest Bowen <ernie@turing.une.edu.au> now defines
special meaning to the first 2 bits of config("lib_debug"):
bit 0 set => messages printed when inputisterminal
bit 1 set => messages printed when reading from a file
The lib/regress.cal regression suite does:
config("lib_debug", -4);
to eliminate lib messages (both bit 0 and bit 1 are not set).
Fixed misc compile warnings and notices.
Following is the change from calc version 2.10.3t5.38 to 2.11.0t0: Following is the change from calc version 2.10.3t5.38 to 2.11.0t0:

55
HOWTO.INSTALL Normal file
View File

@@ -0,0 +1,55 @@
Installing calc in 4 easy steps:
1) Look at the makefile, and adjust it to suit your needs.
Here are some Makefile hints:
Select a compiler set by commenting in the appropriate set
of cc options. As shipped the Makefile assumes a gcc-like
environment such as Linux. If a more appropriate cc set if
found below, comment out the Linux set and comment in that
set or edit the gcc set or the common cc set as needed.
You may or may not need RANLIB when building libraries.
As shipped the Makefile assumes RANLIB is needed.
Comment the in/out the RANLIB value if ranlib does
not work or does not exist.
You may want to change the default pager used by calc.
As shipped the Makefile assumes 'more'. On your system
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,
include files and calc libs are to be installed. As shipped
the Makefile assumes a TOPDIR of /usr/local/lib.
Set BINDIR to the place where calc is installed. As shipped
the Makefile assumes a BINDIR /usr/local/bin.
Adjust other Makefile variables as needed.
2) build calc:
make all
==> We are interested in any compiler warnings (and errors) that
you may find. See the BUGS file if you find any compiler
warning or errors.
3) test calc:
make check
==> If you run into problems, follow the BUGS file instructions.
4) install calc:
make install
We suggest that you might want to read the README file and look at
the calc help subsystem. See the README file for details.

178
Makefile
View File

@@ -314,7 +314,8 @@ CATEXT= 1
# The cat page is not built or installed # The cat page is not built or installed
# #
# If in doubt and you don't want to fool with man pages, set MANDIR # If in doubt and you don't want to fool with man pages, set MANDIR
# and CATDIR to empty and ignore the lines below. # and CATDIR to empty and ignore the NROFF, NROFF_ARG and MANMAKE
# lines below.
# #
NROFF= nroff NROFF= nroff
#NROFF= #NROFF=
@@ -516,7 +517,6 @@ ALLOW_CUSTOM= -DCUSTOM
# ICFLAGS are given to ${CC} for intermediate progs # ICFLAGS are given to ${CC} for intermediate progs
# #
# CCMAIN are flags for ${CC} when files with main() instead of CFLAGS # CCMAIN are flags for ${CC} when files with main() instead of CFLAGS
# CCSHS are flags given to ${CC} for compiling shs.c & shs1.c instead of CFLAGS
# #
# LCFLAGS are CC-style flags for ${LINT} # LCFLAGS are CC-style flags for ${LINT}
# LDFLAGS are flags given to ${CC} for linking .o files # LDFLAGS are flags given to ${CC} for linking .o files
@@ -526,6 +526,53 @@ ALLOW_CUSTOM= -DCUSTOM
# #
### ###
# #
# Linux set
#
# Tested on Red Hat 6.0 Linux but should run on almost any Linux release.
#
# for better performance, set the following above:
# DEBUG= -O2
#
CCWARN= -Wall -Wno-implicit -Wno-comment
CCOPT= ${DEBUG} ${NO_SHARED}
CCMISC=
#
CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC}
ICFLAGS= ${CCWARN} ${CCMISC}
#
CCMAIN= ${ICFLAGS}
#
LCFLAGS=
LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
ILDFLAGS=
#
CC= ${PURIFY} gcc
#
###
#
# gcc set (some call it gcc2, some call it gcc)
#
# for better performance, set the following above:
# DEBUG= -O2
#
#CCWARN= -Wall -Wno-implicit -Wno-comment
#CCOPT= ${DEBUG} ${NO_SHARED}
#CCMISC=
#
#CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC}
#ICFLAGS= ${CCWARN} ${CCMISC}
#
#CCMAIN= ${ICFLAGS}
#
#LCFLAGS=
#LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
#ILDFLAGS=
#
#CC= ${PURIFY} gcc
#CC= ${PURIFY} gcc2
#
###
#
# common cc set # common cc set
# #
#CCWARN= #CCWARN=
@@ -536,38 +583,6 @@ ALLOW_CUSTOM= -DCUSTOM
#ICFLAGS= ${CCWARN} ${CCMISC} #ICFLAGS= ${CCWARN} ${CCMISC}
# #
#CCMAIN= ${ICFLAGS} #CCMAIN= ${ICFLAGS}
#CCSHS= ${CFLAGS}
#
#LCFLAGS=
#LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
#ILDFLAGS=
#
#CC= ${PURIFY} cc
#
###
#
# SGI IRIX5.3 (or earlier) -o32 C Compiler
#
# You must set above:
# RANLIB=:
# LONGLONG_BITS= 0
#
# for better performance, set the following above:
# DEBUG= -O2 -g3
#
# If you have the directory /usr/lib/nonshared, then set the following above:
# NO_SHARED= -non_shared
# LD_NO_SHARED= -Wl,-rdata_shared
#
#CCWARN= -fullwarn -woff 835
#CCOPT= ${DEBUG} ${NO_SHARED}
#CCMISC= -use_readonly_const
#
#CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC}
#ICFLAGS= ${CCWARN} ${CCMISC}
#
#CCMAIN= ${ICFLAGS}
#CCSHS= ${CFLAGS}
# #
#LCFLAGS= #LCFLAGS=
#LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
@@ -599,7 +614,6 @@ ALLOW_CUSTOM= -DCUSTOM
#ICFLAGS= ${CCWARN} ${CCMISC} #ICFLAGS= ${CCWARN} ${CCMISC}
# #
#CCMAIN= ${ICFLAGS} #CCMAIN= ${ICFLAGS}
#CCSHS=
# #
#LCFLAGS= #LCFLAGS=
#LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
@@ -625,7 +639,6 @@ ALLOW_CUSTOM= -DCUSTOM
#ICFLAGS= ${CCWARN} ${CCMISC} #ICFLAGS= ${CCWARN} ${CCMISC}
# #
#CCMAIN= ${ICFLAGS} #CCMAIN= ${ICFLAGS}
#CCSHS= ${CFLAGS}
# #
#LCFLAGS= #LCFLAGS=
#LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
@@ -645,7 +658,6 @@ ALLOW_CUSTOM= -DCUSTOM
#ICFLAGS= ${CCWARN} ${CCMISC} #ICFLAGS= ${CCWARN} ${CCMISC}
# #
#CCMAIN= ${ICFLAGS} #CCMAIN= ${ICFLAGS}
#CCSHS= ${CFLAGS}
# #
#LCFLAGS= #LCFLAGS=
#LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
@@ -655,20 +667,22 @@ ALLOW_CUSTOM= -DCUSTOM
# #
### ###
# #
# Solaris 2.x Sun cc compiler # Solaris Sun cc compiler set
# #
# for better performance, set the following above: # for better performance, set the following above:
# DEBUG= -O # DEBUG= -O
# #
# We need -DFORCE_STDC to make use of ANSI-C like features and
# to avoid the use of -Xc (which as a lose performance wise).
#
#CCWARN= #CCWARN=
#CCOPT= ${DEBUG} ${NO_SHARED} #CCOPT= ${DEBUG} ${NO_SHARED}
#CCMISC=-Xc #CCMISC= -DFORCE_STDC
# #
#CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC} #CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC}
#ICFLAGS= ${CCWARN} ${CCMISC} #ICFLAGS= ${CCWARN} ${CCMISC}
# #
#CCMAIN= ${ICFLAGS} #CCMAIN= ${ICFLAGS}
#CCSHS= ${CFLAGS}
# #
#LCFLAGS= #LCFLAGS=
#LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
@@ -678,30 +692,7 @@ ALLOW_CUSTOM= -DCUSTOM
# #
### ###
# #
# Red Hat Linux 6.0 and BSDI's BSD/OS 4.0 (or later) set # BSDI's BSD/OS 4.0 (or later) set
#
# for better performance, set the following above:
# DEBUG= -O2
#
CCWARN= -Wall -Wno-implicit -Wno-comment
CCOPT= ${DEBUG} ${NO_SHARED}
CCMISC=
#
CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC}
ICFLAGS= ${CCWARN} ${CCMISC}
#
CCMAIN= ${ICFLAGS}
CCSHS= ${CFLAGS}
#
LCFLAGS=
LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
ILDFLAGS=
#
CC= ${PURIFY} gcc
#
###
#
# gcc set (some call it gcc2, some call it gcc)
# #
# for better performance, set the following above: # for better performance, set the following above:
# DEBUG= -O2 # DEBUG= -O2
@@ -714,14 +705,34 @@ CC= ${PURIFY} gcc
#ICFLAGS= ${CCWARN} ${CCMISC} #ICFLAGS= ${CCWARN} ${CCMISC}
# #
#CCMAIN= ${ICFLAGS} #CCMAIN= ${ICFLAGS}
#CCSHS= ${CFLAGS}
# #
#LCFLAGS= #LCFLAGS=
#LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED} #LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
#ILDFLAGS= #ILDFLAGS=
# #
#CC= ${PURIFY} gcc #CC= ${PURIFY} gcc
#CC= ${PURIFY} gcc2 #
###
#
# Dec Alpha / Compaq Tru64 cc (non-gnu) compiler set
#
# for better performance, set the following above:
# DEBUG= -O2
#
#CCWARN=
#CCOPT= ${DEBUG} ${NO_SHARED}
#CCMISC=
#
#CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC}
#ICFLAGS= ${CCWARN} ${CCMISC}
#
#CCMAIN= ${ICFLAGS}
#
#LCFLAGS=
#LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
#ILDFLAGS=
#
#CC= ${PURIFY} cc
############################################################################## ##############################################################################
#-=-=-=-=-=-=-=-=- Be careful if you change something below -=-=-=-=-=-=-=-=-# #-=-=-=-=-=-=-=-=- Be careful if you change something below -=-=-=-=-=-=-=-=-#
@@ -764,7 +775,7 @@ LIBSRC= addop.c assocfunc.c blkcpy.c block.c byteswap.c \
file.c func.c hash.c help.c hist.c input.c jump.c label.c \ file.c func.c hash.c help.c hist.c input.c jump.c label.c \
lib_calc.c lib_util.c listfunc.c matfunc.c math_error.c \ lib_calc.c lib_util.c listfunc.c matfunc.c math_error.c \
md5.c obj.c opcodes.c pix.c poly.c prime.c qfunc.c qio.c \ md5.c obj.c opcodes.c pix.c poly.c prime.c qfunc.c qio.c \
qmath.c qmod.c qtrans.c quickhash.c shs.c shs1.c size.c \ qmath.c qmod.c qtrans.c quickhash.c seed.c shs.c shs1.c size.c \
string.c symbol.c token.c value.c version.c zfunc.c zio.c \ string.c symbol.c token.c value.c version.c zfunc.c zio.c \
zmath.c zmod.c zmul.c zprime.c zrand.c zrandom.c zmath.c zmod.c zmul.c zprime.c zrand.c zrandom.c
@@ -778,7 +789,7 @@ LIBOBJS= addop.o assocfunc.o blkcpy.o block.o byteswap.o calcerr.o \
file.o func.o hash.o help.o hist.o input.o jump.o label.o \ file.o func.o hash.o help.o hist.o input.o jump.o label.o \
lib_calc.o lib_util.o listfunc.o matfunc.o math_error.o \ lib_calc.o lib_util.o listfunc.o matfunc.o math_error.o \
md5.o obj.o opcodes.o pix.o poly.o prime.o qfunc.o qio.o \ md5.o obj.o opcodes.o pix.o poly.o prime.o qfunc.o qio.o \
qmath.o qmod.o qtrans.o quickhash.o shs.o shs1.o size.o \ qmath.o qmod.o qtrans.o quickhash.o seed.o shs.o shs1.o size.o \
string.o symbol.o token.o value.o version.o zfunc.o zio.o \ string.o symbol.o token.o value.o version.o zfunc.o zio.o \
zmath.o zmod.o zmul.o zprime.o zrand.o zrandom.o zmath.o zmod.o zmul.o zprime.o zrand.o zrandom.o
@@ -920,7 +931,7 @@ 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 README.FIRST ${UTIL_MISC_SRC} calc.man lint.sed README.OLD HOWTO.INSTALL ${UTIL_MISC_SRC}
# complete list of .o files # complete list of .o files
# #
@@ -973,17 +984,11 @@ calc.o: calc.c ${MAKE_FILE}
${CC} ${CCMAIN} ${CCOPT} ${ALLOW_CUSTOM} -c calc.c ${CC} ${CCMAIN} ${CCOPT} ${ALLOW_CUSTOM} -c calc.c
custom.o: custom.c ${MAKE_FILE} custom.o: custom.c ${MAKE_FILE}
${CC} ${CCOPT} ${ALLOW_CUSTOM} -c custom.c ${CC} ${CFLAGS} ${ALLOW_CUSTOM} -c custom.c
hist.o: hist.c ${MAKE_FILE} hist.o: hist.c ${MAKE_FILE}
${CC} ${CFLAGS} ${TERMCONTROL} -c hist.c ${CC} ${CFLAGS} ${TERMCONTROL} -c hist.c
shs.o: shs.c ${MAKE_FILE}
${CC} ${CCSHS} -c shs.c
shs1.o: shs1.c ${MAKE_FILE}
${CC} ${CCSHS} -c shs1.c
func.o: func.c ${MAKE_FILE} func.o: func.c ${MAKE_FILE}
${CC} ${CFLAGS} ${ALLOW_CUSTOM} -c func.c ${CC} ${CFLAGS} ${ALLOW_CUSTOM} -c func.c
@@ -2254,11 +2259,11 @@ bsdilist: ${DISTLIST} ${BUILD_H_SRC} calc.1
## ##
check: all ./lib/regress.cal ${REGRESS_CAL} check: all ./lib/regress.cal ${REGRESS_CAL}
${CALC_ENV} ./calc -i -q read regress ${CALC_ENV} ./calc -d -q read regress
chk: ./lib/regress.cal ${REGRESS_CAL} chk: ./lib/regress.cal ${REGRESS_CAL}
${V} echo '=-=-=-=-= start of $@ rule =-=-=-=-=' ${V} echo '=-=-=-=-= start of $@ rule =-=-=-=-='
${CALC_ENV} ./calc -i -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 =-=-=-=-='
## ##
@@ -2328,7 +2333,6 @@ env:
@echo "CFLAGS=${CFLAGS}"; echo "" @echo "CFLAGS=${CFLAGS}"; echo ""
@echo "ICFLAGS=${ICFLAGS}"; echo "" @echo "ICFLAGS=${ICFLAGS}"; echo ""
@echo "CCMAIN=${CCMAIN}"; echo "" @echo "CCMAIN=${CCMAIN}"; echo ""
@echo "CCSHS=${CCSHS}"; echo ""
@echo "LCFLAGS=${LCFLAGS}"; echo "" @echo "LCFLAGS=${LCFLAGS}"; echo ""
@echo "LDFLAGS=${LDFLAGS}"; echo "" @echo "LDFLAGS=${LDFLAGS}"; echo ""
@echo "ILDFLAGS=${ILDFLAGS}"; echo "" @echo "ILDFLAGS=${ILDFLAGS}"; echo ""
@@ -2745,6 +2749,7 @@ byteswap.o: longbits.h
byteswap.o: qmath.h byteswap.o: qmath.h
byteswap.o: zmath.h byteswap.o: zmath.h
calc.o: alloc.h calc.o: alloc.h
calc.o: args.h
calc.o: block.h calc.o: block.h
calc.o: byteswap.h calc.o: byteswap.h
calc.o: calc.c calc.o: calc.c
@@ -2780,6 +2785,7 @@ calc.o: symbol.h
calc.o: token.h calc.o: token.h
calc.o: value.h calc.o: value.h
calc.o: zmath.h calc.o: zmath.h
calc_errno.o: calc_errno.c
calcerr.o: calcerr.c calcerr.o: calcerr.c
calcerr.o: calcerr.h calcerr.o: calcerr.h
calcerr.o: have_const.h calcerr.o: have_const.h
@@ -2957,6 +2963,7 @@ func.o: alloc.h
func.o: block.h func.o: block.h
func.o: byteswap.h func.o: byteswap.h
func.o: calc.h func.o: calc.h
func.o: calc_errno.h
func.o: calcerr.h func.o: calcerr.h
func.o: cmath.h func.o: cmath.h
func.o: config.h func.o: config.h
@@ -3323,7 +3330,6 @@ obj.o: symbol.h
obj.o: value.h obj.o: value.h
obj.o: zmath.h obj.o: zmath.h
opcodes.o: alloc.h opcodes.o: alloc.h
opcodes.o: args.h
opcodes.o: block.h opcodes.o: block.h
opcodes.o: byteswap.h opcodes.o: byteswap.h
opcodes.o: calc.h opcodes.o: calc.h
@@ -3508,6 +3514,18 @@ quickhash.o: value.h
quickhash.o: zmath.h quickhash.o: zmath.h
quickhash.o: zrand.h quickhash.o: zrand.h
quickhash.o: zrandom.h quickhash.o: zrandom.h
seed.o: alloc.h
seed.o: byteswap.h
seed.o: endian_calc.h
seed.o: have_malloc.h
seed.o: have_memmv.h
seed.o: have_newstr.h
seed.o: have_stdlib.h
seed.o: have_string.h
seed.o: longbits.h
seed.o: qmath.h
seed.o: seed.c
seed.o: zmath.h
shs.o: align32.h shs.o: align32.h
shs.o: alloc.h shs.o: alloc.h
shs.o: block.h shs.o: block.h

117
README
View File

@@ -1,68 +1,87 @@
# Copyright (c) 1997 David I. Bell Dear calc user,
# Permission is granted to use, distribute, or modify this source,
# provided that this copyright notice remains intact.
#
# Arbitrary precision calculator.
I am allowing this calculator to be freely distributed for your enjoyment. See the HOWTO.INSTALL file for information on how to build and install calc.
Like all multi-precision programs, you should not depend absolutely on
its results, since bugs in such programs can be insidious and only rarely
show up.
-dbell- To be sure that your version of calc is up to date, check out:
p.s. By Landon Curt Noll: http://reality.sgi.com/chongo/calc/calc-download.html
Building calc in 3 easy steps: We are interested in any/all feedback on recent versions of calc.
In particular we would like to hear about:
1) Look at the makefile, and adjust it to suit your needs. * compiler warnings
* compile problems
* regression test problems (try: make check)
* special compile flags/options that you needed
* Makefile problems
* help file problems
* misc nits and typos
Here are some Makefile hints: We would like to offer a clean compile across a wide verity of platforms,
so if you can test on several, so much the better!
In the past, some people have had to adjust the VARARG or If you run into problems, see the BUGS file.
TERMCONTROL because the Makefile cannot always guess
correctly for certain systems. You may need to play with
these values if you experience problems.
The default compiler used is 'cc'. The default compiler flag
is '-O'. If you have gcc, or gcc v2 (or better) you should use
that instead. Some compilers allow for optimization beyond
just -O (gcc v2 has -O2, mips cc has -O3). You should select
the best flag for speed optimization. Calc can be cpu intensive
so selecting a quality compiler and good optimization level can
really pay off.
2) build calc:
make all
3) test calc:
make check
==>>>If you run into problems, follow the instructions in the BUGS file<<<==
=-= =-=
For further reading: Calc is distributed with an extensive collection of help files that
are accessible from the command line. The following assume that you
are running calc from the distribution directory or that you have
installed calc. In these examples, the ">" is the calc prompt, not
something that you type in.
LIBRARY For list of help topics:
explains how programs can use libcalc.a to take advantage
of the calc multi-precision routines. > help
For overview of calc overview:
> help intro
> help overview
> help command
> help define
> help statement
> help variable
For list of builtin functions:
> help builtin
C programmers should note some unexpected differences in the calc syntax:
> help unexpected
Calc is shipped with a library of calc scripts. For a list see:
> help stdlib
=-=
See the file:
help/todo help/todo
current wish list for calc
CHANGES or run:
recent changes to calc
BUGS calc 'help todo'
known bugs, mis-features and how to report problems
help/full for a wish/todo list. Code contributions are welcome.
full set of calc documentation
=-= =-=
David I. Bell dbell@auug.org.au To join the calc-tester mailing list. Send a request to:
chongo@toad.com <Landon Curt Noll -- chongo@toad.com> /\../\
calc-tester-request@postofc.corp.sgi.com
Your message body (not the subject) should consist of:
subscribe calc-tester address
end
name your_full_name
where ``address'' is your EMail address and ``your_full_name'' is
your full name.
The calc web site is located at:
http://reality.sgi.com/chongo/calc

View File

@@ -1,52 +0,0 @@
Dear alpha tester,
Thanks for taking the time to try out this alpha version of calc! We are
interested in any/all feedback that you may have on this version. In
particular we would like to hear about:
* compile problems
* regression test problems (try: make check)
* compiler warnings
* special compile flags/options that you needed
* Makefile problems
* help file problems
* misc nits and typos
We would like to offer a clean compile across a wide verity of platforms,
so if you can test on several, so much the better!
Calc distributions may be obtained from:
ftp://ftp.uu.net/pub/calc
If you don't have ftp access to that site, or if you do not find a more
recent version (you may have a special pre-released version that is
more advanced than what is in the ftp archive) send EMail to:
chongo@toad.com
Indicate the version you have and that you would like a more up
to date version.
=-=
Misc items TODO before Beta release:
* improve the coverage in the 'SEE ALSO' help file lists
* where reasonable, be sure that regress.cal tests builtin functions
* add the Blum-Blum-Shub random() generator code
* add code to allow of the reading, writing and processing of binary data
* add shs, shs-1 and md5 hashing functions. Use align32.h.
* add mod h*2^n+/-1 function for integers
* be sure that CHANGES is up to date,
look over the help/todo file and update as needed,
revisit issues in the BUGS file and
change this file :-)
* clean the source code and document it better

73
README.OLD Normal file
View File

@@ -0,0 +1,73 @@
# Copyright (c) 1997 David I. Bell
# Permission is granted to use, distribute, or modify this source,
# provided that this copyright notice remains intact.
#
# Arbitrary precision calculator.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTE: This is an old historic README. We recommend that
you read README and HOWTO.INSTALL for more info.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I am allowing this calculator to be freely distributed for your enjoyment.
Like all multi-precision programs, you should not depend absolutely on
its results, since bugs in such programs can be insidious and only rarely
show up.
-dbell-
p.s. By Landon Curt Noll:
Building calc in 3 easy steps:
1) Look at the makefile, and adjust it to suit your needs.
Here are some Makefile hints:
In the past, some people have had to adjust the VARARG or
TERMCONTROL because the Makefile cannot always guess
correctly for certain systems. You may need to play with
these values if you experience problems.
The default compiler used is 'cc'. The default compiler flag
is '-O'. If you have gcc, or gcc v2 (or better) you should use
that instead. Some compilers allow for optimization beyond
just -O (gcc v2 has -O2, mips cc has -O3). You should select
the best flag for speed optimization. Calc can be cpu intensive
so selecting a quality compiler and good optimization level can
really pay off.
2) build calc:
make all
3) test calc:
make check
==>>>If you run into problems, follow the instructions in the BUGS file<<<==
=-=
For further reading:
LIBRARY
explains how programs can use libcalc.a to take advantage
of the calc multi-precision routines.
help/todo
current wish list for calc
CHANGES
recent changes to calc
BUGS
known bugs, mis-features and how to report problems
help/full
full set of calc documentation
=-=
David I. Bell dbell@auug.org.au
chongo <Landon Curt Noll> /\../\

26
addop.c
View File

@@ -135,6 +135,7 @@ endfunc(void)
{ {
register FUNC *fp; /* function just finished */ register FUNC *fp; /* function just finished */
unsigned long size; /* size of just created function */ unsigned long size; /* size of just created function */
long index;
if (oldop != OP_RETURN) { if (oldop != OP_RETURN) {
addop(OP_UNDEF); addop(OP_UNDEF);
@@ -163,14 +164,23 @@ endfunc(void)
size += dumpop(&fp->f_opcodes[size]); size += dumpop(&fp->f_opcodes[size]);
} }
} }
if ((inputisterminal() && conf->lib_debug & 1) ||
(!inputisterminal() && conf->lib_debug & 2)) {
printf("%s(", fp->f_name);
for (index = 0; index < fp->f_paramcount; index++) {
if (index)
putchar(',');
printf("%s", paramname(index));
}
printf(") ");
if (functions[newindex])
printf("re");
printf("defined\n");
}
if (functions[newindex]) { if (functions[newindex]) {
freenumbers(functions[newindex]); freenumbers(functions[newindex]);
free(functions[newindex]); free(functions[newindex]);
if (inputisterminal() || conf->lib_debug >= 0)
printf("%s() redefined\n", fp->f_name);
} }
else if (inputisterminal() || conf->lib_debug >= 0)
printf("%s() defined\n", fp->f_name);
functions[newindex] = fp; functions[newindex] = fp;
objuncache(); objuncache();
} }
@@ -228,7 +238,8 @@ rmuserfunc(char *name)
return; return;
freenumbers(functions[index]); freenumbers(functions[index]);
free(functions[index]); free(functions[index]);
if (!inputisterminal() && conf->lib_debug >= 0) if ((inputisterminal() && conf->lib_debug & 1) ||
(!inputisterminal() && conf->lib_debug & 2))
printf("%s() undefined\n", name); printf("%s() undefined\n", name);
functions[index] = NULL; functions[index] = NULL;
} }
@@ -438,6 +449,11 @@ addop(long op)
case OP_GLOBALADDR: case OP_GLOBALADDR:
diff = 1 + PTR_SIZE; diff = 1 + PTR_SIZE;
break; break;
case OP_UNDEF:
fp->f_opcodecount -= 1;
oldop = OP_NOP;
oldoldop = OP_NOP;
return;
default: default:
cut = FALSE; cut = FALSE;
} }

View File

@@ -17,7 +17,7 @@
#ifdef HAVE_MALLOC_H #ifdef HAVE_MALLOC_H
# include <malloc.h> # include <malloc.h>
#else #else
# if defined(__STDC__) && __STDC__ != 0 #if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
extern void *malloc(); extern void *malloc();
extern void *realloc(); extern void *realloc();
extern void free(); extern void free();
@@ -36,7 +36,7 @@
# if defined(HAVE_NEWSTR) # if defined(HAVE_NEWSTR)
extern void *memcpy(); extern void *memcpy();
extern void *memset(); extern void *memset();
# if defined(__STDC__) && __STDC__ != 0 #if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
extern size_t strlen(); extern size_t strlen();
# else # else
extern long strlen(); extern long strlen();
@@ -65,7 +65,7 @@ extern int strcmp();
#if !defined(HAVE_MEMMOVE) #if !defined(HAVE_MEMMOVE)
# undef CALC_SIZE_T # undef CALC_SIZE_T
# if defined(__STDC__) && __STDC__ != 0 #if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
# define CALC_SIZE_T size_t # define CALC_SIZE_T size_t
# else # else
# define CALC_SIZE_T long # define CALC_SIZE_T long

48
block.c
View File

@@ -71,7 +71,7 @@ static void blkchk(BLOCK*);
BLOCK * BLOCK *
blkalloc(int len, int chunk) blkalloc(int len, int chunk)
{ {
BLOCK *new; /* new block allocated */ BLOCK *nblk; /* new block allocated */
/* /*
* firewall * firewall
@@ -84,8 +84,8 @@ blkalloc(int len, int chunk)
/* /*
* allocate BLOCK * allocate BLOCK
*/ */
new = (BLOCK *)malloc(sizeof(BLOCK)); nblk = (BLOCK *)malloc(sizeof(BLOCK));
if (new == NULL) { if (nblk == NULL) {
math_error("cannot allocate block"); math_error("cannot allocate block");
/*NOTREACHED*/ /*NOTREACHED*/
} }
@@ -93,23 +93,23 @@ blkalloc(int len, int chunk)
/* /*
* initialize BLOCK * initialize BLOCK
*/ */
new->blkchunk = chunk; nblk->blkchunk = chunk;
new->maxsize = ((len+chunk)/chunk)*chunk; nblk->maxsize = ((len+chunk)/chunk)*chunk;
new->data = (USB8*)malloc(new->maxsize); nblk->data = (USB8*)malloc(nblk->maxsize);
if (new->data == NULL) { if (nblk->data == NULL) {
math_error("cannot allocate block data storage"); math_error("cannot allocate block data storage");
/*NOTREACHED*/ /*NOTREACHED*/
} }
memset(new->data, 0, new->maxsize); memset(nblk->data, 0, nblk->maxsize);
new->datalen = len; nblk->datalen = len;
/* /*
* return BLOCK * return BLOCK
*/ */
if (conf->calc_debug > 0) { if (conf->calc_debug > 0) {
blkchk(new); blkchk(nblk);
} }
return new; return nblk;
} }
@@ -227,7 +227,7 @@ blkchk(BLOCK *blk)
BLOCK * BLOCK *
blkrealloc(BLOCK *blk, int newlen, int newchunk) blkrealloc(BLOCK *blk, int newlen, int newchunk)
{ {
USB8 *new; /* realloced storage */ USB8 *nblk; /* realloced storage */
int newmax; /* new maximum stoage size */ int newmax; /* new maximum stoage size */
/* /*
@@ -258,20 +258,20 @@ blkrealloc(BLOCK *blk, int newlen, int newchunk)
if (newmax != blk->maxsize) { if (newmax != blk->maxsize) {
/* reallocate new storage */ /* reallocate new storage */
new = (USB8*)realloc(blk->data, newmax); nblk = (USB8*)realloc(blk->data, newmax);
if (new == NULL) { if (nblk == NULL) {
math_error("cannot reallocate block storage"); math_error("cannot reallocate block storage");
/*NOTREACHED*/ /*NOTREACHED*/
} }
/* clear any new storage */ /* clear any new storage */
if (newmax > blk->maxsize) { if (newmax > blk->maxsize) {
memset(new + blk->maxsize, 0, (newmax - blk->maxsize)); memset(nblk+blk->maxsize, 0, (newmax-blk->maxsize));
} }
blk->maxsize = newmax; blk->maxsize = newmax;
/* restore the data pointers */ /* restore the data pointers */
blk->data = new; blk->data = nblk;
} }
/* /*
@@ -391,13 +391,13 @@ blktrunc(BLOCK *blk)
BLOCK * BLOCK *
blk_copy(BLOCK *blk) blk_copy(BLOCK *blk)
{ {
BLOCK *new; /* copy of blk */ BLOCK *nblk; /* copy of blk */
/* /*
* malloc new block * malloc new block
*/ */
new = (BLOCK *)malloc(sizeof(BLOCK)); nblk = (BLOCK *)malloc(sizeof(BLOCK));
if (new == NULL) { if (nblk == NULL) {
math_error("blk_copy: cannot malloc BLOCK"); math_error("blk_copy: cannot malloc BLOCK");
/*NOTREACHED*/ /*NOTREACHED*/
} }
@@ -405,18 +405,18 @@ blk_copy(BLOCK *blk)
/* /*
* duplicate most of the block * duplicate most of the block
*/ */
*new = *blk; *nblk = *blk;
/* /*
* duplicate block data * duplicate block data
*/ */
new->data = (USB8 *)malloc(blk->maxsize); nblk->data = (USB8 *)malloc(blk->maxsize);
if (new->data == NULL) { if (nblk->data == NULL) {
math_error("blk_copy: cannot duplicate block data"); math_error("blk_copy: cannot duplicate block data");
/*NOTREACHED*/ /*NOTREACHED*/
} }
memcpy(new->data, blk->data, blk->maxsize); memcpy(nblk->data, blk->data, blk->maxsize);
return new; return nblk;
} }

382
calc.c
View File

@@ -11,7 +11,6 @@
#include <pwd.h> #include <pwd.h>
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h> #include <ctype.h>
#include <setjmp.h>
#define CALC_C #define CALC_C
#include "calc.h" #include "calc.h"
@@ -37,30 +36,11 @@
#include <stdlib.h> #include <stdlib.h>
#endif #endif
/* /*
* external and static definitions * static definitions and functions
*/
extern int abortlevel; /* current level of aborts */
extern BOOL inputwait; /* TRUE if in a terminal input wait */
extern jmp_buf jmpbuf; /* for errors */
extern int isatty(int tty); /* TRUE if fd is a tty */
extern int p_flag; /* TRUE => pipe mode */
extern int q_flag; /* TRUE => don't execute rc files */
extern int u_flag; /* TRUE => unbuffer stdin and stdout */
extern char *pager; /* $PAGER or default */
extern int stdin_tty; /* TRUE if stdin is a tty */
extern char *program; /* our name */
extern char cmdbuf[]; /* command line expression */
extern char *version(void); /* return version string */
/*
* forward static functions
*/ */
static char *usage = "usage: %s [-c] [-C] [-d] [-e] [-h] [-i] [-m mode]\n"
"\t[-n] [-p] [-q] [-u] [-v] [[--] calc_cmd ...]\n";
static void intint(int arg); /* interrupt routine */ static void intint(int arg); /* interrupt routine */
@@ -70,124 +50,127 @@ static void intint(int arg); /* interrupt routine */
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
static char *str; /* current option string or expression */
int want_defhelp = 0; /* 1=> we only want the default help */ int want_defhelp = 0; /* 1=> we only want the default help */
int cmdlen; /* length of the command string */
extern char *optarg; /* option argument */
extern int optind; /* option index */
int c; /* option */
long i; long i;
char *p;
/* /*
* parse args * parse args
*/ */
program = argv[0]; program = argv[0];
argc--; while ((c = getopt(argc, argv, "Cehim:npquvcd")) != -1) {
argv++; switch (c) {
while ((argc > 0) && (**argv == '-')) { case 'C':
for (str = &argv[0][1]; *str; str++) switch (*str) {
case 'C':
#if defined(CUSTOM) #if defined(CUSTOM)
allow_custom = TRUE; allow_custom = TRUE;
break; break;
#else #else /* CUSTOM */
fprintf(stderr,
"Calc was built with custom functions "
"disabled, -C usage is disallowed\n");
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
exit(1);
#endif /* CUSTOM */
case 'e':
no_env = TRUE;
break;
case 'h':
want_defhelp = 1;
break;
case 'i':
ign_errmax = TRUE;
break;
case 'm':
if (argv[0][2]) {
p = &argv[0][2];
} else if (argc > 1) {
p = argv[1];
argc--;
argv++;
} else {
fprintf(stderr, "-m requires an arg\n");
/*
* we are too early in processing to
* call libcalc_call_me_last()
* nothing to cleanup
*/
exit(1);
}
if (p[1] != '\0' || *p < '0' || *p > '7') {
fprintf(stderr, "unknown -m arg\n");
/*
* we are too early in processing to
* call libcalc_call_me_last()
* nothing to cleanup
*/
exit(1);
}
allow_read = (((*p-'0') & 04) > 0);
allow_write = (((*p-'0') & 02) > 0);
allow_exec = (((*p-'0') & 01) > 0);
break;
case 'n':
new_std = TRUE;
break;
case 'p':
p_flag = TRUE;
break;
case 'q':
q_flag = TRUE;
break;
case 'u':
u_flag = TRUE;
break;
case 'v':
printf("%s (version %s)\n",
CALC_TITLE, version());
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
exit(0);
default:
fprintf(stderr,
"usage: %s [-C] [-e] [-h] [-i] [-m mode] [-n] [-p]\n",
program);
fprintf(stderr, "\t[-q] [-u] [calc_cmd ...]\n");
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
exit(1);
}
argc--;
argv++;
}
cmdbuf[0] = '\0';
str = cmdbuf;
while (--argc >= 0) {
i = (long)strlen(*argv);
if (i+3 >= MAXCMD) {
fprintf(stderr, "command in arg list too long\n");
/* /*
* we are too early in processing to call * we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup * libcalc_call_me_last() - nothing to cleanup
*/ */
fprintf(stderr,
"%s: calc was built with custom functions "
"disabled, -C usage is disallowed\n", program);
exit(1);
#endif /* CUSTOM */
case 'e':
no_env = TRUE;
break;
case 'h':
want_defhelp = 1;
break;
case 'i':
i_flag = TRUE;
break;
case 'm':
if (optarg[1] == '\0' || *optarg<'0' || *optarg>'7') {
/*
* we are too early in processing to
* call libcalc_call_me_last()
* nothing to cleanup
*/
fprintf(stderr,
"%s: unknown -m arg\n", program);
exit(1);
}
allow_read = (((*optarg-'0') & 04) > 0);
allow_write = (((*optarg-'0') & 02) > 0);
allow_exec = (((*optarg-'0') & 01) > 0);
break;
case 'n':
new_std = TRUE;
break;
case 'p':
p_flag = TRUE;
break;
case 'q':
q_flag = TRUE;
break;
case 'u':
u_flag = TRUE;
break;
case 'c':
c_flag = TRUE;
break;
case 'd':
d_flag = TRUE;
break;
case 'v':
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
printf("%s (version %s)\n", CALC_TITLE, version());
exit(0);
default:
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
fprintf(stderr, usage, program);
exit(1); exit(1);
} }
*str++ = ' ';
strcpy(str, *argv++);
str += i;
str[0] = '\n';
str[1] = '\0';
} }
str = cmdbuf; havecommands = (optind < argc);
/*
* look at the length of any trailing command args
*
* We make room for the trailing '\0\n' as well as an extra guard byte.
*/
for (cmdlen=0, i=optind; i < argc; ++i) {
/* argument + space separator */
cmdlen += strlen(argv[i]) + 1;
}
if (i > MAXCMD) {
/*
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
fprintf(stderr,
"%s: command in arg list is too long\n", program);
exit(1);
}
/*
* We will form a command the remaining args separated by spaces.
*/
cmdbuf[0] = '\0';
if (optind < argc) {
strcpy(cmdbuf, argv[optind]);
cmdlen = strlen(argv[optind]);
for (i=optind+1; i < argc; ++i) {
cmdbuf[cmdlen++] = ' ';
strcpy(cmdbuf+cmdlen, argv[i]);
cmdlen += strlen(argv[i]);
}
cmdbuf[cmdlen++] = '\n';
cmdbuf[cmdlen] = '\0';
}
/* /*
* unbuffered mode * unbuffered mode
@@ -201,8 +184,7 @@ main(int argc, char **argv)
* initialize * initialize
*/ */
libcalc_call_me_first(); libcalc_call_me_first();
stdin_tty = TRUE; /* assume internactive default */ stdin_tty = isatty(0); /* assume stdin is on fd 0 */
conf->tab_ok = TRUE; /* assume internactive default */
if (want_defhelp) { if (want_defhelp) {
givehelp(DEFAULTCALCHELP); givehelp(DEFAULTCALCHELP);
libcalc_call_me_last(); libcalc_call_me_last();
@@ -212,39 +194,25 @@ main(int argc, char **argv)
/* /*
* if allowed or needed, print version and setup bindings * if allowed or needed, print version and setup bindings
*/ */
if (*str == '\0') { if (!havecommands && stdin_tty) {
/* if (!d_flag) {
* check for pipe mode and/or non-tty stdin
*/
if (!p_flag) {
stdin_tty = isatty(0); /* assume stdin is on fd 0 */
}
/*
* empty string arg is no string
*/
str = NULL;
/*
* if tty, setup bindings
*/
if (stdin_tty) {
printf("%s (version %s)\n", CALC_TITLE, version()); printf("%s (version %s)\n", CALC_TITLE, version());
printf("[%s]\n\n", printf("[%s]\n\n",
"Type \"exit\" to exit, or \"help\" for help."); "Type \"exit\" to exit, or \"help\" for help.");
switch (hist_init(calcbindings)) { }
switch (hist_init(calcbindings)) {
case HIST_NOFILE: case HIST_NOFILE:
fprintf(stderr, fprintf(stderr,
"Cannot open bindings file \"%s\", %s.\n", "%s: Cannot open bindings file \"%s\", "
calcbindings, "fancy editing disabled"); "fancy editing disabled.\n",
program, calcbindings);
break; break;
case HIST_NOTTY: case HIST_NOTTY:
fprintf(stderr, fprintf(stderr,
"Cannot set terminal modes, %s.\n", "%s: Cannot set terminal modes, "
"fancy editing disabled"); "fancy editing disabled\n", program);
break; break;
}
} }
} }
@@ -256,53 +224,87 @@ main(int argc, char **argv)
/* /*
* reset/initialize the computing environment * reset/initialize the computing environment
*/ */
if (post_init) { if (post_init)
initialize(); initialize();
} else { post_init = TRUE;
/* initialize already done, jmpbuf is ready */
post_init = TRUE;
}
/*
* if arg mode or non-tty mode, just do the work and be gone
*/
if (str || !stdin_tty) {
if (q_flag == FALSE && allow_read) {
runrcfiles();
q_flag = TRUE;
}
if (str)
(void) openstring(str);
else
(void) openterminal();
start_done = TRUE;
getcommands(FALSE);
libcalc_call_me_last();
exit(0);
}
}
/* if in arg mode, we should not get here */
if (str) {
libcalc_call_me_last();
exit(1);
} }
/* /*
* process commands * (re)establish the interrupt handler
*/ */
if (!start_done) {
reinitialize();
}
(void) signal(SIGINT, intint); (void) signal(SIGINT, intint);
start_done = TRUE;
getcommands(TRUE); /*
* execute calc code based on the run state
*/
if (run_state == RUN_PRE_BEGIN) {
if (!q_flag && allow_read) {
run_state = RUN_PRE_RCFILES;
runrcfiles();
}
run_state = RUN_POST_RCFILES;
}
if (run_state == RUN_PRE_RCFILES) {
fprintf(stderr, "Execution error in rcfiles\n");
if ((c_flag && !stoponerror) || stoponerror < 0) {
getcommands(FALSE);
run_state = RUN_POST_RCFILES;
} else {
if ((havecommands && !i_flag) || !stdin_tty)
run_state = RUN_STOP_ON_ERROR;
else if (havecommands)
run_state = RUN_POST_CMD_ARGS;
else
run_state = RUN_POST_RCFILES;
}
}
if (run_state == RUN_POST_RCFILES) {
if (havecommands) {
run_state = RUN_PRE_CMD_ARGS;
(void) openstring(cmdbuf);
getcommands(FALSE);
}
run_state = RUN_POST_CMD_ARGS;
}
if (run_state == RUN_PRE_CMD_ARGS) {
fprintf(stderr, "Execution error in commands\n");
if ((c_flag && !stoponerror) || stoponerror < 0) {
getcommands(FALSE);
run_state = RUN_POST_CMD_ARGS;
} else {
closeinput();
if (!stdin_tty || !i_flag)
run_state = RUN_STOP_ON_ERROR;
else
run_state = RUN_POST_CMD_ARGS;
}
}
if (run_state == RUN_POST_CMD_ARGS) {
if (stdin_tty && ((havecommands && !i_flag) || p_flag))
run_state = RUN_NOT_TOP_LEVEL;
else
openterminal();
} else if (run_state == RUN_TOP_LEVEL) {
if (!stdin_tty && (!c_flag || stoponerror) &&
stoponerror >= 0) {
run_state = RUN_STOP_ON_ERROR;
} else if ((c_flag && !stoponerror) || stoponerror < 0)
getcommands(FALSE);
else
reinitialize();
}
if (run_state < RUN_NOT_TOP_LEVEL) {
run_state = RUN_TOP_LEVEL;
getcommands(TRUE);
}
/* /*
* all done * all done
*/ */
libcalc_call_me_last(); libcalc_call_me_last();
/* exit(0); */ return (run_state == RUN_STOP_ON_ERROR ||
return 0; run_state == RUN_UNKNOWN) ? 1 : 0;
} }
@@ -339,7 +341,8 @@ math_error(char *fmt, ...)
if (funcname && (*funcname != '*')) if (funcname && (*funcname != '*'))
fprintf(stderr, "\"%s\": ", funcname); fprintf(stderr, "\"%s\": ", funcname);
if (funcline && ((funcname && (*funcname != '*')) || !inputisterminal())) if (funcline && ((funcname && (*funcname != '*')) ||
!inputisterminal()))
fprintf(stderr, "line %ld: ", funcline); fprintf(stderr, "line %ld: ", funcline);
va_start(ap, fmt); va_start(ap, fmt);
vsprintf(buf, fmt, ap); vsprintf(buf, fmt, ap);
@@ -349,7 +352,8 @@ math_error(char *fmt, ...)
if (post_init) { if (post_init) {
longjmp(jmpbuf, 1); longjmp(jmpbuf, 1);
} else { } else {
fprintf(stderr, "no jmpbuf jumpback point - ABORTING!!!\n"); fprintf(stderr, "It is too early provide a command line prompt "
"so we must simply exit. Sorry!\n");
/* /*
* don't call libcalc_call_me_last() -- we might loop * don't call libcalc_call_me_last() -- we might loop
* and besides ... this is an unusual internal error case * and besides ... this is an unusual internal error case

50
calc.h
View File

@@ -10,6 +10,7 @@
#if !defined(__CALC_H__) #if !defined(__CALC_H__)
#define __CALC_H__ #define __CALC_H__
#include <setjmp.h>
#include "value.h" #include "value.h"
@@ -26,7 +27,7 @@
#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 */
#define PATHSIZE 1024 /* maximum length of path name */ #define MAX_CALCRC 1024 /* maximum length of $CALCRC */
#define HOMECHAR '~' /* char which indicates home directory */ #define HOMECHAR '~' /* char which indicates home directory */
#define DOTCHAR '.' /* char which indicates current directory */ #define DOTCHAR '.' /* char which indicates current directory */
#define PATHCHAR '/' /* char which separates path components */ #define PATHCHAR '/' /* char which separates path components */
@@ -37,7 +38,7 @@
#define SYMBOLSIZE 256 /* maximum symbol name size */ #define SYMBOLSIZE 256 /* maximum symbol name size */
#define MAXINDICES 20 /* maximum number of indices for objects */ #define MAXINDICES 20 /* maximum number of indices for objects */
#define MAXLABELS 100 /* maximum number of user labels in function */ #define MAXLABELS 100 /* maximum number of user labels in function */
#define MAXOBJECTS 10 /* maximum number of object types */ #define MAXOBJECTS 128 /* maximum number of object types */
#define MAXSTRING 1024 /* maximum size of string constant */ #define MAXSTRING 1024 /* maximum size of string constant */
#define MAXSTACK 1000 /* maximum depth of evaluation stack */ #define MAXSTACK 1000 /* maximum depth of evaluation stack */
#define MAXFILES 20 /* maximum number of opened files */ #define MAXFILES 20 /* maximum number of opened files */
@@ -58,6 +59,8 @@
#define ABORT_MATH 3 /* abort on any math operation */ #define ABORT_MATH 3 /* abort on any math operation */
#define ABORT_NOW 4 /* abort right away */ #define ABORT_NOW 4 /* abort right away */
#define ERRMAX 20 /* default errmax value */
/* /*
* File ids corresponding to standard in, out, error, and when not in use. * File ids corresponding to standard in, out, error, and when not in use.
*/ */
@@ -144,15 +147,34 @@ extern void showerrors(void);
*/ */
extern void initialize(void); extern void initialize(void);
extern void reinitialize(void); extern void reinitialize(void);
extern int isatty(int tty); /* TRUE if fd is a tty */
extern char *version(void); /* return version string */
extern int post_init; /* TRUE => setjmp for math_error is ready */
/* /*
* Global data definitions. * global flags and definitions
*/ */
extern int abortlevel; /* current level of aborts */
extern BOOL inputwait; /* TRUE if in a terminal input wait */
extern jmp_buf jmpbuf; /* for errors */
extern int p_flag; /* TRUE => pipe mode */
extern int q_flag; /* TRUE => don't execute rc files */
extern int u_flag; /* TRUE => unbuffer stdin and stdout */
extern int d_flag; /* TRUE => disable heading, lib_debug == 0 */
extern int c_flag; /* TRUE => continue after error if permitted */
extern int i_flag; /* TRUE => try to go interactive after error */
extern int stoponerror; /* >0 => stop, <0 => continue, ==0 => use -c */
extern char *pager; /* $PAGER or default */
extern int stdin_tty; /* TRUE if stdin is a tty */
extern int havecommands; /* TRUE if have cmd args) */
extern char *program; /* our name */
extern char cmdbuf[]; /* command line expression */
extern int abortlevel; /* current level of aborts */ extern int abortlevel; /* current level of aborts */
extern BOOL inputwait; /* TRUE if in a terminal input wait */ extern BOOL inputwait; /* TRUE if in a terminal input wait */
extern VALUE *stack; /* execution stack */ extern VALUE *stack; /* execution stack */
extern int start_done; /* TRUE => start up processing finished */
extern int dumpnames; /* TRUE => dump names rather than indices */ extern int dumpnames; /* TRUE => dump names rather than indices */
extern char *calcpath; /* $CALCPATH or default */ extern char *calcpath; /* $CALCPATH or default */
@@ -163,14 +185,28 @@ extern char *shell; /* $SHELL or default */
extern char *program; /* our name (argv[0]) */ extern char *program; /* our name (argv[0]) */
extern int no_env; /* TRUE (-e) => ignore env vars on startup */ extern int no_env; /* TRUE (-e) => ignore env vars on startup */
extern int ign_errmax; /* TRUE (-i) => ignore when errcount exceeds errmax */ extern int errmax; /* if >= 0, error when errcount exceeds errmax */
extern int new_std; /* TRUE (-n) => use newstd configuration */ extern int new_std; /* TRUE (-n) => use newstd configuration */
extern int allow_read; /* FALSE => may not open any files for reading */ extern int allow_read; /* FALSE => may not open any files for reading */
extern int allow_write; /* FALSE => may not open any files for writing */ extern int allow_write; /* FALSE => may not open any files for writing */
extern int allow_exec; /* FALSE => may not execute any commands */ extern int allow_exec; /* FALSE => may not execute any commands */
extern int post_init; /* TRUE => setjmp for math_error is ready */ /*
* calc startup and run state
*/
typedef enum {
RUN_UNKNOWN = -1, /* unknown or unset start state */
RUN_PRE_BEGIN = 0, /* pre-startup state, calc execution started */
RUN_PRE_RCFILES = 1, /* rc files about to or are being evaluated */
RUN_POST_RCFILES = 2, /* rc files have been evaluated */
RUN_PRE_CMD_ARGS = 3, /* cmd_args about to or are being evaluated */
RUN_POST_CMD_ARGS = 4, /* cmd_args have been evaluated */
RUN_TOP_LEVEL = 5, /* running at the top interactive level */
RUN_NOT_TOP_LEVEL = 6, /* running not at the top interactive level */
RUN_STOP_ON_ERROR = 7 /* we need to stop due to errors */
} run;
extern run run_state;
/* /*

535
calc.man
View File

@@ -1,190 +1,356 @@
.\" .\"
.\" Copyright (c) 1994 David I. Bell and Landon Curt Noll .\" Copyright (c) 1993 David I. Bell and Landon Curt Noll
.\" Original man page dated 15nov93
.\" Copyright (c) 1999 David I. Bell and Landon Curt Noll
.\" Permission is granted to use, distribute, or modify this source, .\" Permission is granted to use, distribute, or modify this source,
.\" provided that this copyright notice remains intact. .\" provided that this copyright notice remains intact.
.\" .\"
.\" calculator by David I. Bell .\" calculator by David I. Bell
.\" man page by Landon Noll .\" man page by Landon Noll
.TH calc 1 "^..^" "15nov93" .TH calc 1 "^..^" "15Oct1999"
.SH NAME .SH NAME
calc \- arbitrary precision calculator calc \- arbitrary precision calculator
.SH SYNOPSIS .SH SYNOPSIS
\fIcalc\fP \fIcalc\fP
[\fI\-h\fP] .RB [ \-c ]
[\fI\-m mode\fP] .RB [ \-C ]
[\fI\-p\fP] .RB [ \-d ]
[\fI\-q\fP] .RB [ \-e ]
[\fI\-u\fP] .RB [ \-h ]
[\fI\-v\fP] .RB [ \-i ]
[\fIcalc_cmd \&.\|.\|.\fp] .RB [ \-m\ \&mode ]
.br
.in +5n
.RB [ \-n ]
.RB [ \-p ]
.RB [ \-q ]
.RB [ \-u ]
.RB [ \-v ]
.RB [ calc_cmd\ \&.\|.\|. ]
.in -5n
.SH DESCRIPTION .SH DESCRIPTION
\& \&
.br .br
CALC COMMAND LINE CALC COMMAND LINE
.PP .PP
.TP .TP
\fI\-h\fP .B \-c
Print a help message. Continue reading command lines even after an execution
This option implies \fI \-q\fP. error has caused the abandonment of a line.
This is equivalent to the calc command \fIhelp help\fP. .sp 1
The help facility is disabled unless the \fImode\fP is 5 or 7. For example:
See \fI\-m\fP below. .sp 1
.sp .in +5n
.TP
\fI\-m mode\fP
This flag sets the permission mode of calc.
It controls the ability for \fIcalc\fP to open files
and execute programs.
\fIMode\fP may be a number from 0 to 7.
.sp
The \fImode\fP value is interpreted in a way similar
to that of the \fRchmod(1)\fP octal mode:
.sp
.in +0.5i
.nf .nf
0 do not open any file, do not execute progs calc read many_errors.cal
1 do not open any file
2 do not open files for reading, do not execute progs
3 do not open files for reading
4 do not open files for writing, do not execute progs
5 do not open files for writing
6 do not execute any program
7 allow everything (default mode)
.fi .fi
.in -0.5i .in -5n
.sp .sp 1
If one wished to run calc from a privledged user, one might will cause
want to use \fI\-m 0\fP in an effort to make calc more secure. .B calc
.sp to abort on the first error, whereas:
\fIMode\fP bits for reading and writing apply only on an open. .sp 1
.in +5n
.nf
calc -c read many_errors.cal
.fi
.in -5n
.sp 1
will
cause
.B calc
to try to process each line being read
despite the errors that it encounters.
.TP
.B \-C
Permit the execution of custom builtin functions. Without
this flag, calling the custom() builtin function will
simply generate an error.
.sp 1
Use if this flag may cause
.B calc
to execute functions that
are non-standard and that are not portable. Custom builtin
functions are disabled by default for this reason.
.TP
.B \-d
Disable the printing of the opening title. The printing
of library debug and informational messages is also disabled
as if \fBconfig("lib_debug", 0)\fP had been executed.
.sp 1
For example:
.sp 1
.in +5n
calc 'read qtime; qtime(2)'
.in -5n
.sp 1
will output something like:
.sp 1
.in +5n
.nf
qtime(utc_hr_offset) defined
It's nearly ten past six.
.fi
.in -5n
.sp 1
whereas:
.sp 1
.in +5n
.nf
calc -d 'read qtime; qtime(2)'
.fi
.in -5n
.sp 1
will just say:
.sp 1
.in +5n
.nf
It's nearly ten past six.
.fi
.in -5n
.sp 1
.TP
.B \-e
Ignore any environment variables on startup.
The getenv() builtin will still return values, however.
.TP
.B \-h
Print a help message. This option implies
.BR \-q .
This
is equivalent to the
.B calc
command help help.
The help facility is disabled unless the mode is 5 or 7.
See
.BR \-m .
.TP
.B \-i
Become interactive if possible.
Be default, if
.I calc_cmd
args are given,
.B calc
will execute them and exit.
This flag args are given,
.B calc
will execute them and exit.
This flag will cause
.B calc
to drop into interactive mode after the
commands are executed.
.sp 1
For example:
.sp 1
.in +5n
.nf
calc 2+5
.fi
.in -5n
.sp 1
will print the value 7 and exit whereas:
.sp 1
.in +5n
.nf
calc -i 2+5
.fi
.in -5n
.sp 1
will print the value 7 and prompt the user for more
.B calc
commands.
.TP
.BR \-m " mode"
This flag sets the permission mode of
.BR calc .
It controls the ability for
.B calc
to open files and execute programs.
Mode may be a number from 0 to 7.
.sp 1
The mode value is interpreted in a way similar to that
of the
.BR chmod (1)
octal mode:
.sp 1
.in +5n
.nf
0 do not open any file, do not execute progs
1 do not open any file
2 do not open files for reading, do not execute progs
3 do not open files for reading
4 do not open files for writing, do not execute progs
5 do not open files for writing
6 do not execute any program
7 allow everything (default mode)
.fi
.in -5n
.sp 1
If one wished to run
.B calc
from a privileged user, one might want to use
.B \-m
0 in an effort to make
.B calc
somewhat more secure.
.sp 1
Mode bits for reading and writing apply only on an
open.
Files already open are not effected. Files already open are not effected.
Thus if one wanted to use the \fI\-m 0\fP in an effort to make Thus if one wanted to use the
\fIcalc\fP more secure, but still wanted to read and write a specific .B \-m
file, one might want to do: 0 in an effort to make
.sp .B calc
.in +0.5i somewhat more secure, but still wanted to read and write a specific
file, one might want to do in
.BR sh (1),
.BR ksh (1),
.BR bash (1)-like
shells:
.sp 1
.in +5n
.nf .nf
\fRcalc \-m 0 3<a.file\fP calc -m 0 3<a.file
.fi .fi
.in -0.5i .in -5n
.sp .sp 1
Files presented to \fIcalc\fP in this way are opened in an unknown mode. Files presented to
\fICalc\fP will attempt to read or write them if directed. .B calc
.sp in this way are opened in an
If the \fImode\fP disables opening of files for reading, then unknown mode.
the startup library scripts are disabled as of \fI\-q\fP was given. .B Calc
The reading of key bindings is also disabled when the \fImode\fP will attempt to read or write them if directed.
disables opening of files for reading. .sp 1
If the mode disables opening of files for reading, then
the startup library scripts are disabled as of
.B \-q
was given.
The reading of key bindings is also disabled
when the mode disables opening of files for reading.
.TP .TP
\fI \-p\fP .B \-n
Pipe processing is enabled by use of \-p. For example: Use the new configuration defaults instead of the old
.sp default classic defaults.
.in +0.5i This flag as the same effect
as executing \fBconfig("all", "newcfg")\fP at startup time.
.TP
.B \-p
Pipe processing is enabled by use of
.BR \-p .
For example:
.sp 1
.in +5n
.nf .nf
\fRecho "print 2^21701\-1, 2^23209\-1" | calc \-p | fizzbin\fP calc -p '2^21701-1' | fizzbin
.fi .fi
.in -0.5i .in -5n
.sp .sp 1
In pipe mode, \fIcalc\fP does not prompt, does not print leading tabs In pipe mode,
and does not print the initial header. .B calc
does not prompt, does not print leading
tabs and does not print the initial header.
The
.B \-p
flag overrides
.BR \-i .
.TP .TP
\fI \-q\fP .B \-q
Disable the use of the \fI$CALCRC\fP startup scripts. Disable the use of the $CALCRC startup scripts.
.TP .TP
\fI \-u\fP .B \-u
Disable buffering of stdin and stdout. Disable buffering of stdin and stdout.
.TP .TP
\fI \-v\fP .B \-v
Print the version and exit. Print the
.B calc
version number and exit.
.PP .PP
Without \fIcalc_cmd\fPs, \fIcalc\fP operates interactively. Without
If one or more \fIcalc_cmd\fPs are given on the command line, .IR calc_cmd ,
\fIcalc\fP will execute them and exit. .B calc
The printing of leading tabs on output is disabled operates interactively.
as if \fIconfig("tab",0)\fP had been executed. If one or more
.I calc_cmd
are given on the command line,
.B calc
will execute them and exit.
If
.B \-i
is given,
.B calc
will attempt to become interactive
even of one or more
.I calc_cmd
are given on the command line.
.PP .PP
Normally on startup, \fIcalc\fP attempts to execute a collection Normally on startup,
of library scripts. .B calc
The environment variable \fI$CALCRC\fP (if non-existent then attempts to execute a collection of
a compiled in value) contains a \fI:\fP separated list of library scripts.
startup library scripts. The environment variable $CALCRC (if non-existent
No error conditions are produced if these startup library scripts then a compiled in value) contains a : separated list of startup
are not found. library scripts.
No error conditions are produced if these startup
library scripts are not found.
.PP .PP
If the \fImode\fP disables opening of files for reading, then If the mode disables opening of files for reading, then the startup
the startup library scripts are disabled as of \fI\-q\fP was given library scripts are disabled as of
and \fI$CALCRC\fP as well as the default compiled in value are ignored. .B \-q
was given and $CALCRC as well
as the default compiled in value are ignored.
.PP .PP
Filenames are subject to ``~'' expansion (see below). Filenames are subject to ``~'' expansion (see below).
The environment variable \fI$CALCPATH\fP (if non-existent then The
a compiled in value) contains a \fI:\fP separated list of search environment variable $CALCPATH (if non-existent then a compiled in
directories. value) contains a : separated list of search directories.
If a file does not begin with \fI/\fP, \fI~\fP or \fI./\fP, If a
then it is searched for under each directory listed in the \fI$CALCPATH\fP. file does not begin with /, ~ or ./, then it is searched for under
It is an error if no such readable file is found. each directory listed in the $CALCPATH.
It is an error if no such
readable file is found.
.PP .PP
Calc treats all open files, other than stdin, stdout and stderr .B Calc
as files available for reading and writing. treats all open files, other than stdin, stdout and
One may present calc with an already open file in the following way: stderr as files available for reading and writing.
.sp One may
.in +0.5i present
.B calc
with an already open file using
.BR sh (1),
.BR ksh (1),
.BR bash (1)-like
shells is to:
.sp 1
.in +5n
calc 3<open_file 4<open_file2
.in -5n
.sp 1
For more information use the following
.B calc
commands:
.sp 1
.in +5n
.nf .nf
\fRcalc 3<open_file 4<open_file2\fP
.fi
.in -0.5i
.PP
For more information use the following calc commands:
.PP
.in 1.0i
help usage
.br
help help help help
.br help overview
help usage
help environment help environment
.in -1.0i help config
.PP .fi
OVERVIEW .in -5n
.PP .sp 1
\fICalc\fP is arbitrary precision arithmetic system that uses
a C-like language.
\fICalc\fP is useful as a calculator, an algorithm prototyped
and as a mathematical research tool.
More importantly, \fIcalc\fP provides one with a machine
independent means of computation.
.PP
\fICalc\fP comes with a rich set of builtin mathematical
and programmatic functions.
.PP
\fICalc\fP is distributed with library of scripts.
Written in the same C-like language, library scripts may be
read in and executed during a \fIcalc\fP session.
These library scripts are also provided because they are
useful and to serve as examples of the \fIcalc\fP language.
One may further extend \fIcalc\fP thru the
use of user defined scripts.
.PP
Internally calc represents numeric values as fractions reduced to their
lowest terms.
The numerators and denominators of these factions may grow to
arbitrarily large values.
Numeric values read in are automatically converted into rationals.
The user need not be aware of this internal representation.
.PP
For more information use the following calc commands:
.PP
.in 1.0i
help intro
.br
help builtin
.br
help stdlib
.br
help define
.br
show builtins
.br
show functions
.in -1.0i
.PP .PP
DATA TYPES DATA TYPES
.PP .PP
@@ -199,7 +365,9 @@ multiplication, division, negation, squaring, modulus,
rounding, exponentiation, equality, comparison, printing rounding, exponentiation, equality, comparison, printing
and so on. and so on.
.PP .PP
For more information use the following calc commands: For more information use the following
.B calc
commands:
.PP .PP
.in 1.0i .in 1.0i
help types help types
@@ -220,7 +388,9 @@ procedure.
Values may be grouped together in a matrix, or into a Values may be grouped together in a matrix, or into a
a list that permits stack and queue style operations. a list that permits stack and queue style operations.
.PP .PP
For more information use the following calc commands: For more information use the following
.B calc
commands:
.PP .PP
.in 1.0i .in 1.0i
help variable help variable
@@ -256,7 +426,9 @@ For example:
~chongo/lib/fft_multiply.cal ~chongo/lib/fft_multiply.cal
.in -1.0i .in -1.0i
.PP .PP
For more information use the following calc command: For more information use the following
.B calc
command:
.PP .PP
.in 1.0i .in 1.0i
help file help file
@@ -275,7 +447,9 @@ These include commands such as function definition, help,
reading in library scripts, dump files to a file, error notification, reading in library scripts, dump files to a file, error notification,
configuration control and status. configuration control and status.
.PP .PP
For more information use the following calc command: For more information use the following
.B calc
command:
.PP .PP
.in 1.0i .in 1.0i
help command help command
@@ -295,7 +469,8 @@ help config
.PD 0 .PD 0
.TP 20 .TP 20
${LIBDIR}/*.cal ${LIBDIR}/*.cal
library scripts shipped with calc library scripts shipped with
.B calc
.br .br
.sp .sp
.TP 20 .TP 20
@@ -323,7 +498,9 @@ Default value: ${CALCPATH}
.TP 5 .TP 5
CALCRC CALCRC
On startup (unless \-h or \-q was given on the command On startup (unless \-h or \-q was given on the command
line), calc searches for files along this :-separated line),
.B calc
searches for files along this :-separated
environment variable. environment variable.
.br .br
.sp .sp
@@ -333,7 +510,9 @@ Default value: ${CALCRC}
.TP 5 .TP 5
CALCBINDINGS CALCBINDINGS
On startup (unless \fI\-h\fP or \fI\-q\fP was given on the command On startup (unless \fI\-h\fP or \fI\-q\fP was given on the command
line, or \fI\-m\fP disallows opening files for reading), calc reads line, or \fI\-m\fP disallows opening files for reading),
.B calc
reads
key bindings from the filename specified key bindings from the filename specified
by this environment variable. by this environment variable.
.br .br
@@ -343,9 +522,12 @@ Default value: ${CALCBINDINGS}
.SH CREDIT .SH CREDIT
\& \&
.br .br
The majority of calc was written by David I. Bell. The majority of
.B calc
was written by David I. Bell.
.sp .sp
Calc archives and calc-tester mailing list maintained by Landon Curt Noll. .B Calc
archives and calc-tester mailing list maintained by Landon Curt Noll.
.sp .sp
Thanks for suggestions and encouragement from Peter Miller, Thanks for suggestions and encouragement from Peter Miller,
Neil Justusson, and Landon Noll. Neil Justusson, and Landon Noll.
@@ -378,30 +560,27 @@ Copyright (c) 19xx Ernest Bowen and Landon Curt Noll
Permission is granted to use, distribute, or modify this source, Permission is granted to use, distribute, or modify this source,
provided that this copyright notice remains intact. provided that this copyright notice remains intact.
.sp .sp
Send calc comments, suggestions, bug fixes, enhancements Send comments, suggestions, bug fixes, enhancements
and interesting calc scripts that you would like you see included and interesting
.B calc
scripts that you would like you see included
in future distributions to: in future distributions to:
.sp .sp
.in +0.5i .in +0.5i
dbell@auug.org.au calc-tester-request@postofc.corp.sgi.com
.br
chongo@toad.com
.in -0.5i .in -0.5i
.sp .sp
Landon Noll maintains the official calc ftp archive at: Landon Noll maintains the the
.B calc
web site is located at:
.sp .sp
.in +0.5i .in +0.5i
ftp://ftp.uu.net/pub/calc http://reality.sgi.com/chongo/calc
.in -0.5i .in -0.5i
.sp .sp
Alpha test versions, complete with bugs, untested code and One may join the
experimental features may be fetched (if you are brave) under: .B calc
.sp testing group by sending a request to:
.in +0.5i
http://reality.sgi.com/chongo/calc/
.in -0.5i
.sp
One may join the calc testing group by sending a request to:
.sp .sp
.in +0.5i .in +0.5i
calc-tester-request@postofc.corp.sgi.com calc-tester-request@postofc.corp.sgi.com
@@ -410,14 +589,14 @@ calc-tester-request@postofc.corp.sgi.com
Your message body (not the subject) should consist of: Your message body (not the subject) should consist of:
.sp .sp
.in +0.5i .in +0.5i
.nf
subscribe calc-tester address subscribe calc-tester address
.br
end end
.br
name your_full_name name your_full_name
.fi
.in -0.5i
.sp .sp
where "address" is your EMail address and "your_full_name" where "address" is your EMail address and "your_full_name"
is your full name. is your full name.
.in -0.5i
.sp .sp
Enjoy! Share and Enjoy! :\-)

View File

@@ -71,5 +71,9 @@ END {
if (error > 0 && havebuf0) { if (error > 0 && havebuf0) {
print buf0; print buf0;
} }
exit (error > 0); if (error > 0) {
exit(1);
} else {
exit(0);
}
} }

View File

@@ -81,8 +81,13 @@ static long getinitlist(void);
void void
getcommands(BOOL toplevel) getcommands(BOOL toplevel)
{ {
char name[PATHSIZE+1]; /* program name */ char name[MAXCMD+1+1]; /* program name */
/* firewall */
name[0] = '\0';
name[MAXCMD+1] = '\0';
/* getcommands */
if (!toplevel) if (!toplevel)
enterfilescope(); enterfilescope();
for (;;) { for (;;) {
@@ -256,6 +261,8 @@ getfunction(void)
{ {
char *name; /* parameter name */ char *name; /* parameter name */
int type; /* type of token read */ int type; /* type of token read */
LABEL label;
long index;
(void) tokenmode(TM_DEFAULT); (void) tokenmode(TM_DEFAULT);
if (gettoken() != T_SYMBOL) { if (gettoken() != T_SYMBOL) {
@@ -271,9 +278,11 @@ getfunction(void)
beginfunc(name, FALSE); beginfunc(name, FALSE);
enterfuncscope(); enterfuncscope();
if (gettoken() != T_LEFTPAREN) { if (gettoken() != T_LEFTPAREN) {
scanerror(T_SEMICOLON, "Left parenthesis expected for function"); scanerror(T_SEMICOLON,
"Left parenthesis expected for function");
return; return;
} }
index = 0;
for (;;) { for (;;) {
type = gettoken(); type = gettoken();
if (type == T_RIGHTPAREN) if (type == T_RIGHTPAREN)
@@ -287,12 +296,22 @@ getfunction(void)
case SYM_UNDEFINED: case SYM_UNDEFINED:
case SYM_GLOBAL: case SYM_GLOBAL:
case SYM_STATIC: case SYM_STATIC:
(void) addparam(name); index = addparam(name);
break; break;
default: default:
scanerror(T_NULL, "Parameter \"%s\" is already defined", name); scanerror(T_NULL, "Parameter \"%s\" is already defined", name);
} }
type = gettoken(); type = gettoken();
if (type == T_ASSIGN) {
clearlabel(&label);
addopone(OP_PARAMADDR, index);
addoplabel(OP_JUMPNN, &label);
getopassignment();
addop(OP_ASSIGNPOP);
setlabel(&label);
type = gettoken();
}
if (type == T_RIGHTPAREN) if (type == T_RIGHTPAREN)
break; break;
if (type != T_COMMA) { if (type != T_COMMA) {
@@ -593,25 +612,25 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d
scanerror(T_SEMICOLON, "CONTINUE not within FOR, WHILE, or DO"); scanerror(T_SEMICOLON, "CONTINUE not within FOR, WHILE, or DO");
return; return;
} }
addoplabel(OP_JUMPNE, contlabel); addoplabel(OP_JUMPNZ, contlabel);
break; break;
case T_BREAK: case T_BREAK:
if (breaklabel == NULL_LABEL) { if (breaklabel == NULL_LABEL) {
scanerror(T_SEMICOLON, "BREAK not within FOR, WHILE, or DO"); scanerror(T_SEMICOLON, "BREAK not within FOR, WHILE, or DO");
return; return;
} }
addoplabel(OP_JUMPNE, breaklabel); addoplabel(OP_JUMPNZ, breaklabel);
break; break;
case T_GOTO: case T_GOTO:
if (gettoken() != T_SYMBOL) { if (gettoken() != T_SYMBOL) {
scanerror(T_SEMICOLON, "Missing label in goto"); scanerror(T_SEMICOLON, "Missing label in goto");
return; return;
} }
addop(OP_JUMPNE); addop(OP_JUMPNZ);
addlabel(tokensymbol()); addlabel(tokensymbol());
break; break;
default: default:
addoplabel(OP_JUMPEQ, &label1); addoplabel(OP_JUMPZ, &label1);
rescantoken(); rescantoken();
getstatement(contlabel, breaklabel, NULL_LABEL, NULL_LABEL); getstatement(contlabel, breaklabel, NULL_LABEL, NULL_LABEL);
if (gettoken() != T_ELSE) { if (gettoken() != T_ELSE) {
@@ -662,7 +681,7 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d
contlabel = &label1; contlabel = &label1;
rescantoken(); rescantoken();
(void) getexprlist(); (void) getexprlist();
addoplabel(OP_JUMPNE, &label3); addoplabel(OP_JUMPNZ, &label3);
addoplabel(OP_JUMP, breaklabel); addoplabel(OP_JUMP, breaklabel);
if (gettoken() != T_SEMICOLON) { if (gettoken() != T_SEMICOLON) {
(void) tokenmode(oldmode); (void) tokenmode(oldmode);
@@ -703,7 +722,7 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d
clearlabel(breaklabel); clearlabel(breaklabel);
setlabel(contlabel); setlabel(contlabel);
getcondition(); getcondition();
addoplabel(OP_JUMPEQ, breaklabel); addoplabel(OP_JUMPZ, breaklabel);
getstatement(contlabel, breaklabel, NULL_LABEL, NULL_LABEL); getstatement(contlabel, breaklabel, NULL_LABEL, NULL_LABEL);
addoplabel(OP_JUMP, contlabel); addoplabel(OP_JUMP, contlabel);
setlabel(breaklabel); setlabel(breaklabel);
@@ -726,7 +745,7 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d
} }
setlabel(contlabel); setlabel(contlabel);
getcondition(); getcondition();
addoplabel(OP_JUMPNE, &label3); addoplabel(OP_JUMPNZ, &label3);
setlabel(breaklabel); setlabel(breaklabel);
(void) tokenmode(oldmode); (void) tokenmode(oldmode);
return; return;
@@ -810,6 +829,8 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d
printeol = TRUE; printeol = TRUE;
for (;;) { for (;;) {
switch (gettoken()) { switch (gettoken()) {
case T_RIGHTPAREN:
case T_RIGHTBRACKET:
case T_RIGHTBRACE: case T_RIGHTBRACE:
case T_NEWLINE: case T_NEWLINE:
case T_EOF: case T_EOF:
@@ -1372,6 +1393,21 @@ getassignment (void)
{ {
int type; /* type of expression */ int type; /* type of expression */
switch(gettoken()) {
case T_COMMA:
case T_SEMICOLON:
case T_NEWLINE:
case T_RIGHTPAREN:
case T_RIGHTBRACKET:
case T_RIGHTBRACE:
case T_EOF:
addop(OP_UNDEF);
rescantoken();
return EXPR_RVALUE;
}
rescantoken();
type = getaltcond(); type = getaltcond();
switch (gettoken()) { switch (gettoken()) {
@@ -1436,7 +1472,7 @@ getaltcond(void)
} }
clearlabel(&donelab); clearlabel(&donelab);
clearlabel(&altlab); clearlabel(&altlab);
addoplabel(OP_JUMPEQ, &altlab); addoplabel(OP_JUMPZ, &altlab);
type = getaltcond(); type = getaltcond();
if (gettoken() != T_COLON) { if (gettoken() != T_COLON) {
scanerror(T_SEMICOLON, "Missing colon for conditional expression"); scanerror(T_SEMICOLON, "Missing colon for conditional expression");

View File

@@ -93,7 +93,7 @@ CONFIG oldstd = { /* backward compatible standard configuration */
FALSE, /* skip duplicate block output lines */ FALSE, /* skip duplicate block output lines */
BLK_BASE_HEX, /* block octet print base */ BLK_BASE_HEX, /* block octet print base */
BLK_FMT_HD_STYLE, /* block output format */ BLK_FMT_HD_STYLE, /* block output format */
0, /* calc library debug level */ 3, /* calc library debug level */
0, /* internal calc debug level */ 0, /* internal calc debug level */
0 /* user defined debug level */ 0 /* user defined debug level */
}; };
@@ -128,7 +128,7 @@ CONFIG newstd = { /* new non-backward compatible configuration */
FALSE, /* skip duplicate block output lines */ FALSE, /* skip duplicate block output lines */
BLK_BASE_HEX, /* block octet print base */ BLK_BASE_HEX, /* block octet print base */
BLK_FMT_HD_STYLE, /* block output format */ BLK_FMT_HD_STYLE, /* block output format */
0, /* calc library debug level */ 3, /* calc library debug level */
0, /* internal calc debug level */ 0, /* internal calc debug level */
0 /* user defined debug level */ 0 /* user defined debug level */
}; };
@@ -890,7 +890,7 @@ config_copy(CONFIG *src)
/* /*
* copy over the values * copy over the values
*/ */
*dest = *src; memcpy((void *)dest, (void *)src, sizeof(CONFIG));
/* /*
* clone the pointer values * clone the pointer values

View File

@@ -85,7 +85,7 @@
/* /*
* config defult symbols * config default symbols
*/ */
#define DISPLAY_DEFAULT 20 /* default digits for float display */ #define DISPLAY_DEFAULT 20 /* default digits for float display */
#define EPSILON_DEFAULT "1e-20" /* allowed error for float calculations */ #define EPSILON_DEFAULT "1e-20" /* allowed error for float calculations */
@@ -95,8 +95,6 @@
#define MAXPRINT_DEFAULT 16 /* default number of elements printed */ #define MAXPRINT_DEFAULT 16 /* default number of elements printed */
#define MAXSCANCOUNT 20 /* default max scan errors before an abort */ #define MAXSCANCOUNT 20 /* default max scan errors before an abort */
#define ERRMAX 20 /* default errmax value */
/* /*
* configuration object * configuration object

14
const.c
View File

@@ -27,10 +27,11 @@ initconstants(void)
math_error("Unable to allocate constant table"); math_error("Unable to allocate constant table");
/*NOTREACHED*/ /*NOTREACHED*/
} }
for (i = 0; i < 8; i++) for (i = 0; i < INITCONSTCOUNT; i++)
consttable[i] = initnumbs[i]; consttable[i] = initnumbs[i];
constcount = 8; consttable[INITCONSTCOUNT] = NULL; /* firewall */
constavail = CONSTALLOCSIZE - 8; constcount = INITCONSTCOUNT;
constavail = CONSTALLOCSIZE - INITCONSTCOUNT;
} }
@@ -187,10 +188,9 @@ freeconstant(unsigned long index)
void void
trimconstants(void) trimconstants(void)
{ {
NUMBER **qp; while (constcount > 0 &&
(consttable[constcount-1] == NULL ||
qp = &consttable[constcount]; consttable[constcount-1]->links == 0)) {
while (constcount > 0 && (*--qp)->links == 0) {
constcount--; constcount--;
constavail++; constavail++;
} }

View File

@@ -41,13 +41,13 @@
# #
# Put your custom calc library files here. # Put your custom calc library files here.
# #
CUSTOM_CALC_FILES= argv.cal halflen.cal CUSTOM_CALC_FILES= argv.cal halflen.cal pzasusb8.cal
# The custom help files to install # The custom help files to install
# #
# Put your custom help files here. # Put your custom help files here.
# #
CUSTOM_HELP= argv devnull help sysinfo CUSTOM_HELP= argv devnull help sysinfo pzasusb8
# Any .h files that are needed by programs that use libcustcalc.a # Any .h files that are needed by programs that use libcustcalc.a
# #
@@ -63,7 +63,7 @@ CUSTOM_H_SRC=
# #
# Put your custom .c files here. # Put your custom .c files here.
# #
CUSTOM_SRC= c_argv.c c_devnull.c c_help.c c_sysinfo.c CUSTOM_SRC= c_argv.c c_devnull.c c_help.c c_sysinfo.c c_pzasusb8.c
# Any .o files that are needed by program that use libcustcalc.a. # Any .o files that are needed by program that use libcustcalc.a.
# Don't put ${REQUIRED_OBJ} files in this list. # Don't put ${REQUIRED_OBJ} files in this list.
@@ -72,7 +72,7 @@ CUSTOM_SRC= c_argv.c c_devnull.c c_help.c c_sysinfo.c
# #
# Put your custom .o files here. # Put your custom .o files here.
# #
CUSTOM_OBJ= c_argv.o c_devnull.o c_help.o c_sysinfo.o CUSTOM_OBJ= c_argv.o c_devnull.o c_help.o c_sysinfo.o c_pzasusb8.o
############################################################################## ##############################################################################
#-=-=-=-=-=-=- Defaults in case you want to build from this dir -=-=-=-=-=-=-# #-=-=-=-=-=-=- Defaults in case you want to build from this dir -=-=-=-=-=-=-#
@@ -590,6 +590,11 @@ c_help.o: ../string.h
c_help.o: ../value.h c_help.o: ../value.h
c_help.o: ../zmath.h c_help.o: ../zmath.h
c_help.o: c_help.c c_help.o: c_help.c
c_pzasusb8.o: ../custom.h
c_pzasusb8.o: ../have_const.h
c_pzasusb8.o: ../value.h
c_pzasusb8.o: ../zmath.h
c_pzasusb8.o: c_pzasusb8.c
c_sysinfo.o: ../alloc.h c_sysinfo.o: ../alloc.h
c_sysinfo.o: ../block.h c_sysinfo.o: ../block.h
c_sysinfo.o: ../byteswap.h c_sysinfo.o: ../byteswap.h

70
custom/c_pzasusb8.c Normal file
View File

@@ -0,0 +1,70 @@
/*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted.
*
* Ernest Bowen, following Landon Curt Noll
*/
#if defined(CUSTOM)
#include <stdio.h>
#include "../have_const.h"
#include "../value.h"
#include "../custom.h"
#include "../zmath.h"
/*
* c_pzasusb8 - print numereator of real as if its array of HALFs were
* a string of USB8s
*
* given:
* count = 1;
* vals[0] real number;
*
* returns:
* null
*/
/*ARGSUSED*/
VALUE
c_pzasusb8(char *name, int count, VALUE **vals)
{
VALUE result; /* what we will return */
ZVALUE z; /* numerator of the value */
long half_cnt; /* number of HALFs in the numerator */
USB8 *h; /* octet pointer */
long half_len; /* length of a half in octets */
long i;
long j;
/*
* arg check
*/
result.v_type = V_NULL;
if (vals[0]->v_type != V_NUM) {
math_error("Non-real argument for pzasusb8");
/*NOTREACHED*/
}
/*
* look at the numerator
*/
z = vals[0]->v_num->num;
half_len = sizeof(HALF);
half_cnt = z.len;
/*
* print the octets
*/
h = (USB8 *) z.v;
for (i=0; i < half_cnt; ++i) {
printf("%ld:\t", i);
for (j=0; j < half_len; ++j) {
printf("%02x", (int)(*h++));
}
putchar('\n');
}
return result;
}
#endif /* CUSTOM */

View File

@@ -99,6 +99,7 @@ static struct infoname sys_info[] = {
{"LONGLONG_BITS", "length of a long long, or 0", NULL, (FULL)LONGLONG_BITS}, {"LONGLONG_BITS", "length of a long long, or 0", NULL, (FULL)LONGLONG_BITS},
{"LONG_BITS", "bit length of a long", NULL, (FULL)LONG_BITS}, {"LONG_BITS", "bit length of a long", NULL, (FULL)LONG_BITS},
{"MAP_POPCNT", "number of odd primes in pr_map", NULL, (FULL)MAP_POPCNT}, {"MAP_POPCNT", "number of odd primes in pr_map", NULL, (FULL)MAP_POPCNT},
{"MAX_CALCRC", "maximum allowed length of $CALCRC", NULL, (FULL)MAX_CALCRC},
{"MAXCMD", "max length of command invocation", NULL, (FULL)MAXCMD}, {"MAXCMD", "max length of command invocation", NULL, (FULL)MAXCMD},
{"MAXDIM", "max number of dimensions in matrices", NULL, (FULL)MAXDIM}, {"MAXDIM", "max number of dimensions in matrices", NULL, (FULL)MAXDIM},
{"MAXERROR", "max length of error message string", NULL, (FULL)MAXERROR}, {"MAXERROR", "max length of error message string", NULL, (FULL)MAXERROR},
@@ -128,8 +129,6 @@ static struct infoname sys_info[] = {
{"NXT_MAP_PRIME", "smallest odd prime not in pr_map", NULL, (FULL)NXT_MAP_PRIME}, {"NXT_MAP_PRIME", "smallest odd prime not in pr_map", NULL, (FULL)NXT_MAP_PRIME},
{"NXT_PFACT_VAL", "next prime for higher pfact values", NULL, (FULL)NXT_PFACT_VAL}, {"NXT_PFACT_VAL", "next prime for higher pfact values", NULL, (FULL)NXT_PFACT_VAL},
{"OFF_T_BITS", "file offset size in bits", NULL, (FULL)OFF_T_BITS}, {"OFF_T_BITS", "file offset size in bits", NULL, (FULL)OFF_T_BITS},
{"PATHSIZE", "max length of path name", NULL, (FULL)PATHSIZE},
{"PATHSIZE", "max length of path name", NULL, (FULL)PATHSIZE},
{"PIX_32B", "max pix() value", NULL, (FULL)PIX_32B}, {"PIX_32B", "max pix() value", NULL, (FULL)PIX_32B},
{"POW_ALG2", "default size for using REDC for powers", NULL, (FULL)POW_ALG2}, {"POW_ALG2", "default size for using REDC for powers", NULL, (FULL)POW_ALG2},
{"REDC_ALG2", "default size using alternative REDC alg", NULL, (FULL)REDC_ALG2}, {"REDC_ALG2", "default size using alternative REDC alg", NULL, (FULL)REDC_ALG2},
@@ -238,9 +237,10 @@ c_sysinfo(char *name, int count, VALUE **vals)
} else if (vals[0]->v_type == V_STR) { } else if (vals[0]->v_type == V_STR) {
/* convert vals[0] to upper case string */ /* convert vals[0] to upper case string */
buf = (char *)malloc(strlen((char *)vals[0]->v_str)+1); buf = (char *)malloc(strlen((char *)vals[0]->v_str->s_str)+1);
for (q = (char *)vals[0]->v_str, r = buf; *q; ++q, ++r) { for (q = (char *)vals[0]->v_str->s_str, r = buf; *q; ++q, ++r)
if (isascii(*q) && islower(*q)) { {
if (isascii((int)*q) && islower((int)*q)) {
*r = *q - 'a' + 'A'; *r = *q - 'a' + 'A';
} else { } else {
*r = *q; *r = *q;
@@ -262,7 +262,7 @@ c_sysinfo(char *name, int count, VALUE **vals)
/* return value as string */ /* return value as string */
result.v_type = V_STR; result.v_type = V_STR;
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
result.v_str = (STRING *)p->str; result.v_str = makestring(p->str);
} }
/* return found infotype as value */ /* return found infotype as value */

View File

@@ -59,6 +59,7 @@ extern VALUE c_argv(char*, int, VALUE**);
extern VALUE c_devnull(char*, int, VALUE**); extern VALUE c_devnull(char*, int, VALUE**);
extern VALUE c_help(char*, int, VALUE**); extern VALUE c_help(char*, int, VALUE**);
extern VALUE c_sysinfo(char*, int, VALUE**); extern VALUE c_sysinfo(char*, int, VALUE**);
extern VALUE c_pzasusb8(char*, int, VALUE**);
#endif /* CUSTOM */ #endif /* CUSTOM */
@@ -108,6 +109,9 @@ CONST struct custom cust[] = {
{ "sysinfo", "return a calc #define value", { "sysinfo", "return a calc #define value",
0, 1, c_sysinfo }, 0, 1, c_sysinfo },
{ "pzasusb8", "print ZCALUE as USB8",
0, 1, c_pzasusb8 },
#endif /* CUSTOM */ #endif /* CUSTOM */

50
custom/pzasusb8 Normal file
View File

@@ -0,0 +1,50 @@
NAME
pzasusb8 - print a number in hex octets
SYNOPSIS
custom("pzasusb8", arg)
TYPES
arg real
return null
DESCRIPTION
This custom function prints out the numerator of a real value
in octets. Each HALF value is printed in a separate line.
NOTE: The output will vary depending on the size of a HALF
and the byte order of the system. See:
custom("sysinfo", "BASEB")
custom("sysinfo", "CALC_BYTE_ORDER")
foe details.
This custom function is intented for testing of the general
custom interface.
EXAMPLE
> custom("pzasusb8", 0x01020304050607080910111213141516);
0: 13141516
1: 09101112
2: 05060708
3: 01020304
> custom("pzasusb8", 10^25)
0: 4a000000
1: 16140148
2: 00084595
> printf("%x\n", 10^25);
0x84595161401484a000000
LIMITS
calc must be built with ALLOW_CUSTOM= -DCUSTOM
calc must be executed with a -C arg.
LIBRARY
none
SEE ALSO
custom

29
custom/pzasusb8.cal Normal file
View File

@@ -0,0 +1,29 @@
/*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted.
*
* Ernest Bowen, following Landon Curt Noll
*/
print "p(n) prints array in which numerator of n is stored as a";
print "sequence of 2-hex-digits representing unsigned characters.";
print "h(n) printx n in hex notation. This should be the same as";
print "p(n) except for (1) its leading 0x, (2) possible trailing zeros";
print "in p(n), and (3) the order of the hex-digit pairs.";
print "The following example show results for n = isqrt(2e100).";
print "";
define p(n) {custom("pzasusb8", n); print;}
define h(n) = printf("%x\n", n);
n = isqrt(2e100);
print "";
p(n);
h(n);
print "";
print "BASEB: ", custom("sysinfo", "BASEB");
print "CALC_BYTE_ORDER: ", custom("sysinfo", "CALC_BYTE_ORDER");
print "BIG_ENDIAN: ", custom("sysinfo", "BIG_ENDIAN");
print "LITTLE_ENDIAN: ", custom("sysinfo", "LITTLE_ENDIAN");
print "LONG_BITS: ", custom("sysinfo", "LONG_BITS");
print "LONGLONG_BITS: ", custom("sysinfo", "LONGLONG_BITS");

View File

@@ -76,5 +76,5 @@ main(void)
exit(1); exit(1);
} }
/* exit(0); */ /* exit(0); */
return 0; return 0;
} }

1
file.c
View File

@@ -2271,6 +2271,7 @@ freadnum(FILE *fp, VALUE *valptr)
num = newnum; num = newnum;
zden = newden; zden = newden;
} }
zfree(div);
} }
q = qalloc(); q = qalloc();
q->num = num; q->num = num;

110
func.c
View File

@@ -84,6 +84,8 @@ extern void matrandperm(MATRIX *M);
extern void listrandperm(LIST *lp); extern void listrandperm(LIST *lp);
extern int idungetc(FILEID id, int ch); extern int idungetc(FILEID id, int ch);
extern int stoponerror;
/* /*
* if HZ & CLK_TCK are not defined, pick typical values, hope for the best * if HZ & CLK_TCK are not defined, pick typical values, hope for the best
@@ -209,6 +211,28 @@ f_prompt(VALUE *vp)
} }
static VALUE
f_display(int count, VALUE **vals)
{
long oldvalue;
VALUE res;
oldvalue = conf->outdigits;
if (count > 0) {
if (vals[0]->v_type != V_NUM || qisfrac(vals[0]->v_num) ||
qisneg(vals[0]->v_num) || zge31b(vals[0]->v_num->num))
fprintf(stderr,
"Out-of-range arg for display ignored\n");
else
conf->outdigits = qtoi(vals[0]->v_num);
}
res.v_type = V_NUM;
res.v_num = itoq(oldvalue);
return res;
}
/*ARGSUSED*/ /*ARGSUSED*/
static VALUE static VALUE
f_null(int count, VALUE **vals) f_null(int count, VALUE **vals)
@@ -230,33 +254,34 @@ f_str(VALUE *vp)
switch (vp->v_type) { switch (vp->v_type) {
case V_STR: case V_STR:
result.v_str = stringcopy(vp->v_str); result.v_str = stringcopy(vp->v_str);
return result; break;
case V_NULL: case V_NULL:
result.v_str = slink(&_nullstring_); result.v_str = slink(&_nullstring_);
return result; break;
case V_OCTET: case V_OCTET:
result.v_str = charstring(*vp->v_octet); result.v_str = charstring(*vp->v_octet);
return result; break;
case V_NUM: case V_NUM:
math_divertio(); math_divertio();
qprintnum(vp->v_num, MODE_DEFAULT); qprintnum(vp->v_num, MODE_DEFAULT);
cp = math_getdivertedio(); cp = math_getdivertedio();
result.v_str = makestring(cp);
break; break;
case V_COM: case V_COM:
math_divertio(); math_divertio();
comprint(vp->v_com); comprint(vp->v_com);
cp = math_getdivertedio(); cp = math_getdivertedio();
result.v_str = makestring(cp);
break; break;
default: default:
return error_value(E_STR); return error_value(E_STR);
} }
result.v_str = makestring(cp);
return result; return result;
} }
static VALUE static VALUE
f_name (VALUE *vp) f_name(VALUE *vp)
{ {
VALUE result; VALUE result;
char *cp; char *cp;
@@ -767,6 +792,13 @@ f_nextcand(int count, NUMBER **vals)
} }
static NUMBER *
f_seed(void)
{
return pseudo_seed();
}
static NUMBER * static NUMBER *
f_rand(int count, NUMBER **vals) f_rand(int count, NUMBER **vals)
{ {
@@ -1242,6 +1274,7 @@ minlistitems(LIST *lp)
VALUE min; VALUE min;
min.v_type = V_NULL; min.v_type = V_NULL;
term.v_type = V_NULL;
for (ep = lp->l_first; ep; ep = ep->e_next) { for (ep = lp->l_first; ep; ep = ep->e_next) {
vp = &ep->e_value; vp = &ep->e_value;
@@ -1291,6 +1324,7 @@ maxlistitems(LIST *lp)
VALUE max; VALUE max;
max.v_type = V_NULL; max.v_type = V_NULL;
term.v_type = V_NULL;
for (ep = lp->l_first; ep; ep = ep->e_next) { for (ep = lp->l_first; ep; ep = ep->e_next) {
vp = &ep->e_value; vp = &ep->e_value;
@@ -1339,6 +1373,8 @@ f_min(int count, VALUE **vals)
VALUE rel; VALUE rel;
min.v_type = V_NULL; min.v_type = V_NULL;
term.v_type = V_NULL;
while (count-- > 0) { while (count-- > 0) {
vp = *vals++; vp = *vals++;
switch(vp->v_type) { switch(vp->v_type) {
@@ -1390,6 +1426,7 @@ f_max(int count, VALUE **vals)
VALUE rel; VALUE rel;
max.v_type = V_NULL; max.v_type = V_NULL;
term.v_type = V_NULL;
while (count-- > 0) { while (count-- > 0) {
vp = *vals++; vp = *vals++;
@@ -1494,6 +1531,7 @@ sumlistitems(LIST *lp)
VALUE sum; VALUE sum;
sum.v_type = V_NULL; sum.v_type = V_NULL;
term.v_type = V_NULL;
for (ep = lp->l_first; ep; ep = ep->e_next) { for (ep = lp->l_first; ep; ep = ep->e_next) {
vp = &ep->e_value; vp = &ep->e_value;
@@ -1534,6 +1572,8 @@ f_sum(int count, VALUE **vals)
VALUE *vp; VALUE *vp;
sum.v_type = V_NULL; sum.v_type = V_NULL;
term.v_type = V_NULL;
while (count-- > 0) { while (count-- > 0) {
vp = *vals++; vp = *vals++;
switch(vp->v_type) { switch(vp->v_type) {
@@ -4376,11 +4416,7 @@ f_errno(int count, VALUE **vals)
math_error("errno argument out of range"); math_error("errno argument out of range");
/*NOTREACHED*/ /*NOTREACHED*/
} }
newerr = z1tol(vp->v_num->num); newerr = (int) ztoi(vp->v_num->num);
if (newerr >= 32768) {
math_error("errno argument out of range");
/*NOTREACHED*/
}
} }
olderr = set_errno(newerr); olderr = set_errno(newerr);
@@ -4407,7 +4443,7 @@ f_errcount(int count, VALUE **vals)
math_error("errcount argument out of range"); math_error("errcount argument out of range");
/*NOTREACHED*/ /*NOTREACHED*/
} }
newcount = z1tol(vp->v_num->num); newcount = (int) ztoi(vp->v_num->num);
} }
oldcount = set_errcount(newcount); oldcount = set_errcount(newcount);
@@ -4420,23 +4456,21 @@ f_errcount(int count, VALUE **vals)
static VALUE static VALUE
f_errmax(int count, VALUE **vals) f_errmax(int count, VALUE **vals)
{ {
int newmax, oldmax; int oldmax;
VALUE *vp; VALUE *vp;
VALUE result; VALUE result;
newmax = -1; oldmax = errmax;
if (count > 0) { if (count > 0) {
vp = vals[0]; vp = vals[0];
/* arg must be an integer */
if (vp->v_type != V_NUM || qisfrac(vp->v_num) || if (vp->v_type != V_NUM || qisfrac(vp->v_num) ||
qisneg(vp->v_num) || zge31b(vp->v_num->num)) { zge31b(vp->v_num->num))
math_error("errcount argument out of range"); fprintf(stderr,
/*NOTREACHED*/ "Out-of-range arg for errmax ignored\n");
} else
newmax = z1tol(vp->v_num->num); errmax = (int) ztoi(vp->v_num->num);
} }
oldmax = set_errmax(newmax);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = itoq((long) oldmax); result.v_num = itoq((long) oldmax);
@@ -4444,6 +4478,30 @@ f_errmax(int count, VALUE **vals)
} }
static VALUE
f_stoponerror(int count, VALUE **vals)
{
int oldval;
VALUE *vp;
VALUE result;
oldval = stoponerror;
if (count > 0) {
vp = vals[0];
if (vp->v_type != V_NUM || qisfrac(vp->v_num) ||
zge31b(vp->v_num->num))
fprintf(stderr,
"Out-of-range arg for stoponerror ignored\n");
else
stoponerror = (int) ztoi(vp->v_num->num);
}
result.v_type = V_NUM;
result.v_num = itoq((long) oldval);
return result;
}
static VALUE static VALUE
f_fclose(int count, VALUE **vals) f_fclose(int count, VALUE **vals)
{ {
@@ -5169,11 +5227,14 @@ f_strprintf(int count, VALUE **vals)
math_divertio(); math_divertio();
i = idprintf(FILEID_STDOUT, vals[0]->v_str->s_str, i = idprintf(FILEID_STDOUT, vals[0]->v_str->s_str,
count - 1, vals + 1); count - 1, vals + 1);
if (i) if (i) {
free(math_getdivertedio());
return error_value(E_STRPRINTF2); return error_value(E_STRPRINTF2);
}
cp = math_getdivertedio(); cp = math_getdivertedio();
result.v_type = V_STR; result.v_type = V_STR;
result.v_str = makenewstring(cp); result.v_str = makenewstring(cp);
free(cp);
return result; return result;
} }
@@ -5917,6 +5978,7 @@ f_putenv(int count, VALUE **vals)
/* return putenv result */ /* return putenv result */
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = itoq((long) putenv(putenv_str)); result.v_num = itoq((long) putenv(putenv_str));
free(putenv_str);
return result; return result;
} }
@@ -6786,6 +6848,8 @@ static CONST struct builtin builtins[] = {
"digit at specified decimal place of number"}, "digit at specified decimal place of number"},
{"digits", 1, 1, 0, OP_NOP, f_digits, 0, {"digits", 1, 1, 0, OP_NOP, f_digits, 0,
"number of digits in number"}, "number of digits in number"},
{"display", 0, 1, 0, OP_NOP, 0, f_display,
"number of decimal digits for displaying numbers"},
{"dp", 2, 2, 0, OP_NOP, 0, f_dp, {"dp", 2, 2, 0, OP_NOP, 0, f_dp,
"dot product of two vectors"}, "dot product of two vectors"},
{"epsilon", 0, 1, 0, OP_SETEPSILON, 0, 0, {"epsilon", 0, 1, 0, OP_SETEPSILON, 0, 0,
@@ -7136,6 +7200,8 @@ static CONST struct builtin builtins[] = {
"sec of a within accuracy b"}, "sec of a within accuracy b"},
{"sech", 1, 2, 0, OP_NOP, 0, f_sech, {"sech", 1, 2, 0, OP_NOP, 0, f_sech,
"hyperbolic secant of a within accuracy b"}, "hyperbolic secant of a within accuracy b"},
{"seed", 0, 0, 0, OP_NOP, f_seed, 0,
"return a 64 bit seed for a psuedo-random generator"},
{"segment", 2, 3, 0, OP_NOP, 0, f_segment, {"segment", 2, 3, 0, OP_NOP, 0, f_segment,
"specified segment of specified list"}, "specified segment of specified list"},
{"select", 2, 2, 0, OP_NOP, 0, f_select, {"select", 2, 2, 0, OP_NOP, 0, f_select,
@@ -7166,6 +7232,8 @@ static CONST struct builtin builtins[] = {
"seed the random() function"}, "seed the random() function"},
{"ssq", 1, IN, 0, OP_NOP, 0, f_ssq, {"ssq", 1, IN, 0, OP_NOP, 0, f_ssq,
"sum of squares of values"}, "sum of squares of values"},
{"stoponerror", 0, 1, 0, OP_NOP, 0, f_stoponerror,
"assign value to stoponerror flag"},
{"str", 1, 1, 0, OP_NOP, 0, f_str, {"str", 1, 1, 0, OP_NOP, 0, f_str,
"simple value converted to string"}, "simple value converted to string"},
{"strcat", 1,IN, 0, OP_NOP, 0, f_strcat, {"strcat", 1,IN, 0, OP_NOP, 0, f_strcat,

59
hash.c
View File

@@ -147,13 +147,13 @@ hash_free(HASH *state)
HASH * HASH *
hash_copy(HASH *state) hash_copy(HASH *state)
{ {
HASH *new; /* copy of state */ HASH *hnew; /* copy of state */
/* /*
* malloc new state * malloc new state
*/ */
new = (HASH *)malloc(sizeof(HASH)); hnew = (HASH *)malloc(sizeof(HASH));
if (new == NULL) { if (hnew == NULL) {
math_error("hash_init: cannot malloc HASH"); math_error("hash_init: cannot malloc HASH");
/*NOTREACHED*/ /*NOTREACHED*/
} }
@@ -161,8 +161,8 @@ hash_copy(HASH *state)
/* /*
* duplicate state * duplicate state
*/ */
memcpy((void *)new, (void *)state, sizeof(HASH)); memcpy((void *)hnew, (void *)state, sizeof(HASH));
return new; return hnew;
} }
@@ -391,8 +391,8 @@ hash_zvalue(int type, ZVALUE zval, HASH *state)
*/ */
if (zval.len > full_lim) { if (zval.len > full_lim) {
for (j=0; j < zval.len-full_lim-1; j += 2) { for (j=0; j < zval.len-full_lim-1; j += 2) {
half[j] = zval.v[full_lim+i+1]; half[j] = zval.v[full_lim+j+1];
half[j+1] = zval.v[full_lim+i]; half[j+1] = zval.v[full_lim+j];
} }
if (j < zval.len-full_lim) { if (j < zval.len-full_lim) {
half[j] = (HALF)0; half[j] = (HALF)0;
@@ -562,7 +562,7 @@ hash_complex(int type, void *c, HASH *state)
/* /*
* hash_str - hash a string * hash_str - hash a null-terminated string
* *
* given: * given:
* type - hash type (see hash.h) * type - hash type (see hash.h)
@@ -606,6 +606,47 @@ hash_str(int type, char *str, HASH *state)
} }
/*
* hash_STR - hash a STRING
*
* given:
* type - hash type (see hash.h)
* str - the STRING
* state - the state to hash or NULL
*
* returns:
* the new state
*/
HASH *
hash_STR(int type, STRING *str, HASH *state)
{
/*
* initialize if state is NULL
*/
if (state == NULL) {
state = hash_init(type, NULL);
}
/*
* setup for the string hash
*/
if (!state->bytes) {
(state->chkpt)(state);
state->bytes = TRUE;
}
/*
* hash the string
*/
(state->update)(state, (USB8*) str->s_str, (USB32) str->s_len);
/*
* all done
*/
return state;
}
/* /*
* hash_usb8 - hash an array of USB8s * hash_usb8 - hash an array of USB8s
* *
@@ -720,7 +761,7 @@ hash_value(int type, void *v, HASH *state)
/* strings have no setup */ /* strings have no setup */
/* hash this type */ /* hash this type */
state = hash_str(type, value->v_str->s_str, state); state = hash_STR(type, value->v_str, state);
break; break;
case V_MAT: case V_MAT:

View File

@@ -54,7 +54,7 @@ char buf[BUFSIZ];
void void
try(char *fmt, ...) try_this(char *fmt, ...)
{ {
va_list ap; va_list ap;
@@ -79,7 +79,7 @@ main(void)
/* /*
* test variable args and vsprintf/sprintf * test variable args and vsprintf/sprintf
*/ */
try("@%d:%s:%d@", 1, "hi", 2); try_this("@%d:%s:%d@", 1, "hi", 2);
if (strcmp(buf, "@1:hi:2@") != 0) { if (strcmp(buf, "@1:hi:2@") != 0) {
#if !defined(DONT_HAVE_VSPRINTF) #if !defined(DONT_HAVE_VSPRINTF)
/* <stdarg.h> with vsprintf() didn't work */ /* <stdarg.h> with vsprintf() didn't work */
@@ -88,7 +88,7 @@ main(void)
#endif #endif
exit(1); exit(1);
} }
try("%s %d%s%d%d %s", try_this("%s %d%s%d%d %s",
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime"); "Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
if (strcmp(buf, if (strcmp(buf,
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) { "Landon Noll 1st proved that 2^23209-1 was prime") != 0) {

View File

@@ -52,7 +52,7 @@ char buf[BUFSIZ];
#include <varargs.h> #include <varargs.h>
void void
try(char *fmt, ...) try_this(char *fmt, ...)
{ {
va_list ap; va_list ap;
@@ -68,7 +68,7 @@ try(char *fmt, ...)
#else #else
void void
try(char *a, int b, char *c, int d) try_this(char *a, int b, char *c, int d)
{ {
return; return;
} }
@@ -87,7 +87,7 @@ main(void)
/* /*
* test variable args and vsprintf/sprintf * test variable args and vsprintf/sprintf
*/ */
try("@%d:%s:%d@", 1, "hi", 2); try_this("@%d:%s:%d@", 1, "hi", 2);
if (strcmp(buf, "@1:hi:2@") != 0) { if (strcmp(buf, "@1:hi:2@") != 0) {
#if !defined(DONT_HAVE_VSPRINTF) #if !defined(DONT_HAVE_VSPRINTF)
/* <varargs.h> with vsprintf() didn't work */ /* <varargs.h> with vsprintf() didn't work */
@@ -96,7 +96,7 @@ main(void)
#endif #endif
exit(1); exit(1);
} }
try("%s %d%s%d%d %s", try_this("%s %d%s%d%d %s",
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime"); "Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
if (strcmp(buf, if (strcmp(buf,
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) { "Landon Noll 1st proved that 2^23209-1 was prime") != 0) {

View File

@@ -124,7 +124,7 @@ DETAIL_HELP= abs access acos acosh acot acoth acsc acsch address agd append \
pmod polar poly pop popcnt power prevcand prevprime printf prompt \ pmod polar poly pop popcnt power prevcand prevprime printf prompt \
protect ptest push putenv quo quomod rand randbit random randombit \ protect ptest push putenv quo quomod rand randbit random randombit \
randperm rcin rcmul rcout rcpow rcsq re remove reverse rewind rm root \ randperm rcin rcmul rcout rcpow rcsq re remove reverse rewind rm root \
round rsearch runtime saveval scale scan scanf search sec sech \ round rsearch runtime saveval scale scan scanf search sec sech seed \
segment select sgn sha sha1 sin sinh size sizeof sort sqrt srand \ segment select sgn sha sha1 sin sinh size sizeof sort sqrt srand \
srandom ssq str strcat strerror strlen strpos strprintf strscan \ srandom ssq str strcat strerror strlen strpos strprintf strscan \
strscanf substr sum swap system tail tan tanh test time trunc xor strscanf substr sum swap system tail tan tanh test time trunc xor

View File

@@ -8,7 +8,7 @@ Environment variables
If this variable does not exist, a compiled value If this variable does not exist, a compiled value
is used. Typically compiled in value is: is used. Typically compiled in value is:
.:./lib:~/lib:${LIBDIR}/calc .:./lib:~/lib:${LIBDIR}/calc:${LIBDIR}/custom
where ${LIBDIR} is usually: where ${LIBDIR} is usually:

View File

@@ -25,7 +25,7 @@ LIBRARY
none none
SEE ALSO SEE ALSO
rand, srand, randbit, seed, rand, srand, randbit,
isassoc, isatty, isblk, isconfig, isdefined, iserror, iseven, isfile, isassoc, isatty, isblk, isconfig, isdefined, iserror, iseven, isfile,
ishash, isident, isint, islist, ismat, ismult, isnull, isnum, isobj, ishash, isident, isint, islist, ismat, ismult, isnull, isnum, isobj,
isobjtype, isodd, isprime, israndom, isreal, isrel, isobjtype, isodd, isprime, israndom, isreal, isrel,

View File

@@ -27,7 +27,7 @@ LIBRARY
none none
SEE ALSO SEE ALSO
random, srandom, randombit, seed, random, srandom, randombit,
isassoc, isatty, isblk, isconfig, isdefined, iserror, iseven, isfile, isassoc, isatty, isblk, isconfig, isdefined, iserror, iseven, isfile,
ishash, isident, isint, islist, ismat, ismult, isnull, isnum, isobj, ishash, isident, isint, islist, ismat, ismult, isnull, isnum, isobj,
isobjtype, isodd, isprime, isrand, isreal, isrel, isobjtype, isodd, isprime, isrand, isreal, isrel,

View File

@@ -44,7 +44,7 @@
for and overview of the help system. The command: for and overview of the help system. The command:
help builtins help builtin
provides information on built-in mathematical functions, whereas: provides information on built-in mathematical functions, whereas:
@@ -67,6 +67,10 @@
It contains information about differences between C and calc It contains information about differences between C and calc
that may surprize you. that may surprize you.
To learn about calc library files that are shipped with calc, try:
help stdlib
A full and extensive overview of calc may be obtained by: A full and extensive overview of calc may be obtained by:
help full help full

View File

@@ -230,4 +230,4 @@ LIBRARY
long irand(long max) long irand(long max)
SEE ALSO SEE ALSO
srand, randbit, isrand, random, srandom, israndom seed, srand, randbit, isrand, random, srandom, israndom

View File

@@ -40,4 +40,4 @@ LIBRARY
void zrand(long cnt, ZVALUE *res) void zrand(long cnt, ZVALUE *res)
SEE ALSO SEE ALSO
srand, randbit, isrand, random, srandom, israndom seed, srand, randbit, isrand, random, srandom, israndom

View File

@@ -154,4 +154,4 @@ LIBRARY
long irandom(long max) long irandom(long max)
SEE ALSO SEE ALSO
srand, randbit, isrand, rand, srandom, israndom seed, srand, randbit, isrand, rand, srandom, israndom

View File

@@ -39,4 +39,4 @@ LIBRARY
void zrandom(long cnt, ZVALUE *res) void zrandom(long cnt, ZVALUE *res)
SEE ALSO SEE ALSO
srand, randbit, isrand, rand, srandom, israndom seed, srand, randbit, isrand, rand, srandom, israndom

52
help/seed Normal file
View File

@@ -0,0 +1,52 @@
NAME
seed - return a value that may be used to seed a pseudo-random generator
SYNOPSIS
seed()
TYPES
return integer
DESCRIPTION
Generate a pseudo-random seed based on a collection of system and process
information. The seed() builtin function returns a value:
0 <= seed < 2^64
IMPORTANT WARNING:
It should be pointed out that the information collected by seed
is almost certainly non-chaotic. This function is likely not
suitable for applications (such as cryptographic applications)
where the unpredictability of seeds is critical. For such critical
applications, lavarand should be used. Seed:
http://lavarand.sgi.com
for information about seeding a pseudo-random number generator
(such as rand() or random()) with the cryptographic hash of the
digitization of chaotic system.
Given the above warning, this builtin function produces a seed that is
suitable for most applications that desire a different pseudo-random
sequence each time they are run.
The return value of this builtin function should NOT be considered
a random or pseudo-random value. The return value should be used
as an argument to a seed function such as srand() or srandom().
EXAMPLE
> print srand(seed())
RAND state
> print srandom(seed())
RAND state
LIMITS
none
LIBRARY
NUMBER *pseudo_seed(void)
SEE ALSO
seed, srand, randbit, isrand, rand, random, srandom, israndom

View File

@@ -148,4 +148,4 @@ LIBRARY
RAND *zsetrand(RAND *state) RAND *zsetrand(RAND *state)
SEE ALSO SEE ALSO
srandom, randbit, isrand, random, srandom, israndom seed, srandom, randbit, isrand, random, srandom, israndom

View File

@@ -337,4 +337,4 @@ LIBRARY
RAND *zsetrandom(RAND *state) RAND *zsetrandom(RAND *state)
SEE ALSO SEE ALSO
srand, randbit, isrand, random, srandom, israndom seed, srand, randbit, isrand, random, srandom, israndom

View File

@@ -235,3 +235,9 @@ Needed enhancements
One should make available a the fundimental math operations One should make available a the fundimental math operations
on ZVALUE, NUMBER and perhaps COMPLEX (without all of the on ZVALUE, NUMBER and perhaps COMPLEX (without all of the
other stuff) in a separate library. other stuff) in a separate library.
* improve the coverage in the 'SEE ALSO' help file lists
* where reasonable, be sure that regress.cal tests builtin functions
* clean the source code and document it better

View File

@@ -2,7 +2,22 @@ Calc command line
Calc has the following command line: Calc has the following command line:
calc [-C] [-e] [-h] [-i] [-m mode] [-n] [-p] [-q] [-u] [calc_cmd ...] calc [-c] [-C] [-d] [-e] [-h] [-i] [-m mode]
[-n] [-p] [-q] [-u] [-v] [calc_cmd ...]
-c Continue reading command lines even after an execution
error has caused the abandonment of a line.
For example:
calc read many_errors.cal
will cause calc to abort on the first error, whereas:
calc -c read many_errors.cal
will cause calc to try to process each line being read
despite the errors that it encounters.
-C Permit the execution of custom builtin functions. Without -C Permit the execution of custom builtin functions. Without
this flag, calling the custom() builtin function will this flag, calling the custom() builtin function will
@@ -12,6 +27,27 @@ Calc command line
are non-standard and that are not portable. Custom builtin are non-standard and that are not portable. Custom builtin
functions are disabled by default for this reason. functions are disabled by default for this reason.
-d Disable the printing of the opening title. The printing
of library debug and informational messages is also disabled
as if config("lib_debug",0) had been executed.
For example:
calc 'read qtime; qtime(2)'
will output something like:
qtime(utc_hr_offset) defined
It's nearly ten past six.
whereas:
calc -d 'read qtime; qtime(2)'
will just say:
It's nearly ten past six.
-e Ignore any environment variables on startup. The -e Ignore any environment variables on startup. The
getenv() builtin will still return values, however. getenv() builtin will still return values, however.
@@ -19,7 +55,21 @@ Calc command line
is equivalent to the calc command help help. The help is equivalent to the calc command help help. The help
facility is disabled unless the mode is 5 or 7. See -m. facility is disabled unless the mode is 5 or 7. See -m.
-i Do not about if the error count exceeds maxerr(). -i Become interactive if possible. Be default, if calc_cmd
args are given, calc will execute them and exit. This flag
will cause calc to drop into interactive mode after the
commands are executed.
For example:
calc 2+5
will print the value 7 and exit whereas:
calc -i 2+5
will print the value 7 and prompt the user for more
calc commands.
-m mode -m mode
This flag sets the permission mode of calc. It This flag sets the permission mode of calc. It
@@ -38,7 +88,7 @@ Calc command line
6 do not execute any program 6 do not execute any program
7 allow everything (default mode) 7 allow everything (default mode)
If one wished to run calc from a privledged user, one If one wished to run calc from a privileged user, one
might want to use -m 0 in an effort to make calc more might want to use -m 0 in an effort to make calc more
secure. secure.
@@ -46,7 +96,7 @@ Calc command line
open. Files already open are not effected. Thus if one open. Files already open are not effected. Thus if one
wanted to use the -m 0 in an effort to make calc more wanted to use the -m 0 in an effort to make calc more
secure, but still wanted to read and write a specific secure, but still wanted to read and write a specific
file, one might want to do: file, one might want to do in sh, ksh, bash-like shells:
calc -m 0 3<a.file calc -m 0 3<a.file
@@ -59,25 +109,28 @@ Calc command line
given. The reading of key bindings is also disabled given. The reading of key bindings is also disabled
when the mode disables opening of files for reading. when the mode disables opening of files for reading.
-n Use the new configutation defaults instead of the old -n Use the new configuration defaults instead of the old
default classic defaults. This flag as the same effect default classic defaults. This flag as the same effect
as executing config("all", "newcfg") at startup time. as executing config("all", "newcfg") at startup time.
-p Pipe processing is enabled by use of -p. For example: -p Pipe processing is enabled by use of -p. For example:
echo "print 2^21701-1, 2^23209-1" | calc -p | fizzbin calc -p '2^21701-1' | fizzbin
In pipe mode, calc does not prompt, does not print In pipe mode, calc does not prompt, does not print leading
leading tabs and does not print the initial header. tabs and does not print the initial header. The -p flag
overrides -i.
-q Disable the use of the $CALCRC startup scripts. -q Disable the use of the $CALCRC startup scripts.
-u Disable buffering of stdin and stdout. -u Disable buffering of stdin and stdout.
-v Print calc version number and exit.
Without `calc_cmd', calc operates interactively. If one or more Without `calc_cmd', calc operates interactively. If one or more
`calc_cmd' are given on the command line, calc will execute them and `calc_cmd' are given on the command line, calc will execute them and
exit. The printing of leading tabs on output is disabled as if exit. If -i is given, calc will attempt to become interactive
config("tab",0) had been executed. even of one or more `calc_cmd' are given on the command line.
Normally on startup, calc attempts to execute a collection of Normally on startup, calc attempts to execute a collection of
library scripts. The environment variable $CALCRC (if non-existent library scripts. The environment variable $CALCRC (if non-existent
@@ -98,7 +151,8 @@ Calc command line
Calc treats all open files, other than stdin, stdout and Calc treats all open files, other than stdin, stdout and
stderr as files available for reading and writing. One may stderr as files available for reading and writing. One may
present calc with an already open file in the following way: present calc with an already open file using sh, ksh or bash-like
shells is to:
calc 3<open_file 4<open_file2 calc 3<open_file 4<open_file2

1
hist.h
View File

@@ -30,7 +30,6 @@
#define DOTCHAR '.' /* char which indicates current directory */ #define DOTCHAR '.' /* char which indicates current directory */
#define PATHCHAR '/' /* char which separates path components */ #define PATHCHAR '/' /* char which separates path components */
#define LISTCHAR ':' /* char which separates paths in a list */ #define LISTCHAR ':' /* char which separates paths in a list */
#define PATHSIZE 1024 /* maximum length of path name */
/* /*

84
input.c
View File

@@ -91,20 +91,51 @@ opensearchfile(char *name, char *pathlist, char *extension, int rd_once)
{ {
int i; int i;
char *cp; char *cp;
char path[PATHSIZE+1]; /* name being searched for */ char *path; /* name being searched for */
struct stat statbuf; /* stat of the path */ struct stat statbuf; /* stat of the path */
unsigned long namelen; /* length of name */
unsigned long extlen; /* length of the extension if non-NULL or 0 */
unsigned long pathlen; /* length of the pathlist if non-NULL or 0 */
/*
* allocate storage for the longest name being searched for
*
* We will allocate more than we could ever want/need.
* The longest we could ever need would be:
*
* pathlist (as a single long string)
* /
* name
* .
* extenstion
* \0
* guard byte
*/
namelen = strlen(name);
if (extension != NULL) {
extlen = strlen(extension);
} else {
extlen = 0;
}
if (pathlist != NULL) {
pathlen = strlen(pathlist);
} else {
pathlen = 0;
}
path = malloc(pathlen+1 + 1 + namelen+1 + extlen+1 + 1 + 1);
if (path == NULL) {
math_error("Cannot allocate filename path buffer");
/*NOTREACHED*/
}
/* /*
* Don't try the extension if the filename already contains it. * Don't try the extension if the filename already contains it.
*/ */
if (extension) { if (extension != NULL && namelen >= extlen &&
unsigned long namelen = strlen(name); strcmp(&name[namelen-extlen], extension) == 0) {
unsigned long extlen = strlen(extension); extension = NULL;
if (namelen >= extlen &&
strcmp(&name[namelen-extlen], extension) == 0)
extension = NULL;
} }
/* /*
* If the name is absolute, or if there is no path list, then * If the name is absolute, or if there is no path list, then
* make one which just searches for the name straight. Then * make one which just searches for the name straight. Then
@@ -127,21 +158,26 @@ opensearchfile(char *name, char *pathlist, char *extension, int rd_once)
*cp++ = PATHCHAR; *cp++ = PATHCHAR;
strcpy(cp, name); strcpy(cp, name);
i = openfile(path); i = openfile(path);
if ((i < 0) && (extension != NULL && extension[0] != '\0')) { if ((i < 0) &&
(extension != NULL && extension[0] != '\0')) {
strcat(path, extension); strcat(path, extension);
i = openfile(path); i = openfile(path);
} }
} while ((i < 0) && *pathlist); } while ((i < 0) && *pathlist);
/* examine what our search produced */ /* examine what our search produced */
if (i < 0) if (i < 0) {
free(path);
return i; return i;
}
if (cip->i_fp == NULL) { if (cip->i_fp == NULL) {
/* cannot find a file to open */ /* cannot find a file to open */
free(path);
return -3; return -3;
} }
if (fstat(fileno(cip->i_fp), &statbuf) < 0) { if (fstat(fileno(cip->i_fp), &statbuf) < 0) {
/* unable to fstat the open file */ /* unable to fstat the open file */
free(path);
return -4; return -4;
} }
@@ -149,6 +185,7 @@ opensearchfile(char *name, char *pathlist, char *extension, int rd_once)
if (rd_once == TRUE && isinoderead(&statbuf) >= 0) { if (rd_once == TRUE && isinoderead(&statbuf) >= 0) {
/* file is in readset and reopen is false */ /* file is in readset and reopen is false */
closeinput(); closeinput();
free(path);
return 1; return 1;
} }
@@ -156,10 +193,12 @@ opensearchfile(char *name, char *pathlist, char *extension, int rd_once)
if (addreadset(name, path, &statbuf) < 0) { if (addreadset(name, path, &statbuf) < 0) {
/* cannot add to readset */ /* cannot add to readset */
closeinput(); closeinput();
free(path);
return -1; return -1;
} }
/* file was added to/updated in readset */ /* file was added to/updated in readset */
free(path);
return 0; return 0;
} }
@@ -189,7 +228,7 @@ homeexpand(char *name)
char *home2; /* fullpath of the home directory */ char *home2; /* fullpath of the home directory */
char *fullpath; /* the malloced expanded path */ char *fullpath; /* the malloced expanded path */
char *after; /* after the ~user or ~ */ char *after; /* after the ~user or ~ */
char username[PATHSIZE+1]; /* extratced username */ char *username; /* extratced username */
/* firewall */ /* firewall */
if (name[0] != HOMECHAR) if (name[0] != HOMECHAR)
@@ -217,11 +256,15 @@ homeexpand(char *name)
} }
/* just malloc the home directory and return it */ /* just malloc the home directory and return it */
fullpath = (char *)malloc(strlen(ent->pw_dir)+1); fullpath = (char *)malloc(strlen(ent->pw_dir)+1);
if (fullpath == NULL) {
return NULL;
}
strcpy(fullpath, ent->pw_dir); strcpy(fullpath, ent->pw_dir);
return fullpath; return fullpath;
} }
if (after-name > PATHSIZE+1) { username = (char *) malloc(after-name + 1 + 1);
/* username is too big */ if (username == NULL) {
/* failed to malloc username */
return NULL; return NULL;
} }
strncpy(username, name+1, after-name-1); strncpy(username, name+1, after-name-1);
@@ -229,6 +272,7 @@ homeexpand(char *name)
/* get that user's home directory */ /* get that user's home directory */
ent = (struct passwd *)getpwnam(username); ent = (struct passwd *)getpwnam(username);
free(username);
if (ent == NULL) { if (ent == NULL) {
/* unknown user */ /* unknown user */
return NULL; return NULL;
@@ -241,6 +285,9 @@ homeexpand(char *name)
* build the fullpath given the home directory * build the fullpath given the home directory
*/ */
fullpath = (char *)malloc(strlen(home2)+strlen(after)+1); fullpath = (char *)malloc(strlen(home2)+strlen(after)+1);
if (fullpath == NULL) {
return NULL;
}
sprintf(fullpath, "%s%s", home2, after); sprintf(fullpath, "%s%s", home2, after);
return fullpath; return fullpath;
} }
@@ -264,7 +311,7 @@ f_open(char *name, char *mode)
*/ */
if (!allow_read && !allow_write) { if (!allow_read && !allow_write) {
/* no reads and no writes means no opens! */ /* no reads and no writes means no opens! */
if (start_done) { if (run_state > RUN_PRE_BEGIN) {
fprintf(stderr, fprintf(stderr,
"open of %s mode %s - %s\n", name, mode, "open of %s mode %s - %s\n", name, mode,
"open for read or write disallowed by -m\n"); "open for read or write disallowed by -m\n");
@@ -272,7 +319,7 @@ f_open(char *name, char *mode)
return NULL; return NULL;
} else if (!allow_read && strchr(mode, 'r') != NULL) { } else if (!allow_read && strchr(mode, 'r') != NULL) {
/* reading new files disallowed */ /* reading new files disallowed */
if (start_done) { if (run_state > RUN_PRE_BEGIN) {
fprintf(stderr, fprintf(stderr,
"open of %s mode %s - %s\n", name, mode, "open of %s mode %s - %s\n", name, mode,
"open for read disallowed by -m\n"); "open for read disallowed by -m\n");
@@ -283,7 +330,7 @@ f_open(char *name, char *mode)
strchr(mode, 'a') != NULL || strchr(mode, 'a') != NULL ||
strchr(mode, '+') != NULL)) { strchr(mode, '+') != NULL)) {
/* writing new files disallowed */ /* writing new files disallowed */
if (start_done) { if (run_state > RUN_PRE_BEGIN) {
fprintf(stderr, fprintf(stderr,
"open of %s mode %s - %s\n", name, mode, "open of %s mode %s - %s\n", name, mode,
"open for write disallowed by -m\n"); "open for write disallowed by -m\n");
@@ -333,6 +380,9 @@ openfile(char *name)
cip->i_fp = fp; cip->i_fp = fp;
cip->i_line = 1; cip->i_line = 1;
cip->i_name = (char *)malloc(strlen(name) + 1); cip->i_name = (char *)malloc(strlen(name) + 1);
if (cip->i_name == NULL) {
return -1;
}
strcpy(cip->i_name, name); strcpy(cip->i_name, name);
return 0; return 0;
} }
@@ -658,7 +708,7 @@ reread(void)
void void
runrcfiles(void) runrcfiles(void)
{ {
char path[PATHSIZE+1]; /* name being searched for */ char path[MAX_CALCRC+1+1]; /* name being searched for */
char *cp; char *cp;
char *newcp; char *newcp;
char *p; char *p;

View File

@@ -44,7 +44,7 @@ CALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.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 \
beer.cal hello.cal test5100.cal test5200.cal randombitrun.cal \ beer.cal hello.cal test5100.cal test5200.cal randombitrun.cal \
randomrun.cal xx_print.cal natnumset.cal randomrun.cal xx_print.cal natnumset.cal qtime.cal
# These files are found (but not built) in the distribution # These files are found (but not built) in the distribution
# #

View File

@@ -1,20 +1,44 @@
# Copyright (c) 1997 David I. Bell and Landon Curt Noll To load a library, try:
# Permission is granted to use, distribute, or modify this source,
# provided that this copyright notice remains intact.
The following calc library files are provided because they serve as read filename
examples of how use the calc language, and/or because the authors thought
them to be useful! You to not need to add the .cal extension to the filename. Calc
will search along the $CALCPATH (see ``help environment'').
Normally a library will simply define some functions. By default,
most libraries will print out a short message when thei are read.
For example:
> read lucas
lucas(h,n) defined
gen_u0(h,n,v1) defined
gen_v1(h,n) defined
ldebug(funct,str) defined
will cause calc to load and execute the 'lucas.cal' library.
Executing the library will cause several functions to be defined.
Executing the lucas function
> lucas(149,60)
1
> lucas(146,61)
0
shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.
=-=
Calc library files are provided because they serve as examples of how use
the calc language, and/or because the authors thought them to be useful!
If you write something that you think is useful, please send it to: If you write something that you think is useful, please send it to:
dbell@auug.org.au calc-tester@postofc.corp.sgi.com
chongo@toad.com {uunet,pyramid,sun}!hoptoad!chongo
By convention, a lib file only defines and/or initializes functions, By convention, a lib file only defines and/or initializes functions,
objects and variables. (The regression test is an exception.) Also by objects and variables. (The regress.cal and testxxx.cal regression test
convention, the a usage message regarding each important object and suite is an exception.) Also by convention, an additional usage message
function is printed at the time of the read. regarding important object and functions is printed.
If a lib file needs to load another lib file, it should use the -once If a lib file needs to load another lib file, it should use the -once
version of read: version of read:
@@ -45,18 +69,29 @@ global variable. By convention, "lib_debug" has the following meanings:
printed at the time of the read in addition printed at the time of the read in addition
to other debug messages to other debug messages
To conform to the above convention, your lib files should end with When config("lib_debug") >= 0, function names and their arg are
lines of the form: printed as they are defined. Sometimes this printing is not enough
information. For example:
* useful obj definitions
* functions with optional args
* functions with optional args where the param() interface is used
For these cases we suggest that you place at the bottom of your code
something like:
if (config("lib_debug") >= 0) { if (config("lib_debug") >= 0) {
print "obj xyz defined"; print "obj xyz defined";
print "funcA(side_a, side_b, side_c) defined"; print "funcA([val1 [, val2]]) defined";
print "funcB(size, mass) defined"; print "funcB(size, mass, ...) defined";
} }
=-= =-=
The following is a brief description of some of the calc library files
that are shipped with calc. See above for example of how to read in
and execute these files.
beer.cal beer.cal
Calc's contribution to the 99 Bottles of Beer web page: Calc's contribution to the 99 Bottles of Beer web page:
@@ -100,7 +135,7 @@ deg.cal
ellip.cal ellip.cal
factor(iN, ia, B, force) efactor(iN, ia, B, force)
Attempt to factor using the elliptic functions: y^2 = x^3 + a*x + b. Attempt to factor using the elliptic functions: y^2 = x^3 + a*x + b.
@@ -160,7 +195,7 @@ mfactor.cal
mod.cal mod.cal
mod(a) lmod(a)
mod_print(a) mod_print(a)
mod_one() mod_one()
mod_cmp(a, b) mod_cmp(a, b)
@@ -250,7 +285,7 @@ pix.cal
pollard.cal pollard.cal
factor(N, N, ai, af) pfactor(N, N, ai, af)
Factor using Pollard's p-1 method. Factor using Pollard's p-1 method.
@@ -276,6 +311,13 @@ psqrt.cal
Calculate square roots modulo a prime Calculate square roots modulo a prime
qtime.cal
qtime(utc_hr_offset)
Print the time as English sentence given the hours offset from UTC.
quat.cal quat.cal
quat(a, b, c, d) quat(a, b, c, d)
@@ -520,6 +562,20 @@ test3400.cal
This script is used by regress.cal to test trig functions. This script is used by regress.cal to test trig functions.
containing objects. containing objects.
test3500.cal
global defaultverbose
global err
testfrem(x, y, verbose)
testgcdrem(x, y, verbose)
testf(str, n, verbose)
testg(str, n, verbose)
testh(str, n, N, verbose)
test3500(verbose, n, N)
This script is used by regress.cal to test the functions frem,
fcnt, gcdrem.
test4000.cal test4000.cal
global defaultverbose global defaultverbose
@@ -617,7 +673,7 @@ varargs.cal
xx_print.cal xx_print.cal
isoctet(a) defined is_octet(a) defined
list_print(a) defined list_print(a) defined
mat_print (a) defined mat_print (a) defined
octet_print(a) defined octet_print(a) defined
@@ -628,3 +684,9 @@ xx_print.cal
error_print(a) defined error_print(a) defined
Demo for the xx_print object routines. Demo for the xx_print object routines.
=-=
# Copyright (c) 1999 David I. Bell and Landon Curt Noll
# Permission is granted to use, distribute, or modify this source,
# provided that this copyright notice remains intact.

View File

@@ -20,7 +20,3 @@ for (i=99; i > 0;) {
bottles = (i!=1) ? "bottles" : "bottle"; bottles = (i!=1) ? "bottles" : "bottle";
print less, bottles, "of beer on the wall!\n"; print less, bottles, "of beer on the wall!\n";
} }
if (config("lib_debug") >= 0) {
/* nothing to do! */
}

View File

@@ -60,7 +60,3 @@ define B(n)
Bnmax = n; Bnmax = n;
return Bn[n]; return Bn[n];
} }
if (config("lib_debug") >= 0) {
print "B(n) defined";
}

View File

@@ -25,7 +25,3 @@ define bigprime(a, m, p)
print " " : n; print " " : n;
} }
} }
if (config("lib_debug") >= 0) {
print "bigprime(a, m, p) defined";
}

View File

@@ -113,11 +113,4 @@ define fixdms(a)
if (config("lib_debug") >= 0) { if (config("lib_debug") >= 0) {
print "obj dms {deg, min, sec} defined"; print "obj dms {deg, min, sec} defined";
print "dms(deg, min, sec) defined";
print "dms_add(a, b) defined";
print "dms_neg(a) defined";
print "dms_sub(a, b) defined";
print "dms_mul(a, b) defined";
print "dms_print(a) defined";
print "dms_abs(a) defined";
} }

View File

@@ -24,7 +24,7 @@
* only an approximation, read "A Course in Number Theory and Cryptography" * only an approximation, read "A Course in Number Theory and Cryptography"
* by Neal Koblitz for a good explanation. * by Neal Koblitz for a good explanation.
* *
* factor(iN, ia, B, force) * efactor(iN, ia, B, force)
* iN is the number to be factored. * iN is the number to be factored.
* ia is the initial value of a in the equation, and each successive * ia is the initial value of a in the equation, and each successive
* value of a is an independent attempt at factoring (default 1). * value of a is an independent attempt at factoring (default 1).
@@ -66,7 +66,7 @@ global b; /* second coefficient */
global f; /* found factor */ global f; /* found factor */
define factor(iN, ia, B, force) define efactor(iN, ia, B, force)
{ {
local C, x, p; local C, x, p;
@@ -165,7 +165,3 @@ define point_pow(p, pow)
} }
return r; return r;
} }
if (config("lib_debug") >= 0) {
print "factor(N, I, B, force) defined";
}

View File

@@ -6,7 +6,3 @@
*/ */
while(1) print "Hello World!"; while(1) print "Hello World!";
if (config("lib_debug") >= 0) {
/* nothing to do */
}

View File

@@ -1029,7 +1029,3 @@ ldebug(funct, str)
} }
return; return;
} }
if (config("lib_debug") >= 0) {
print "lucas(h, n) defined";
}

View File

@@ -374,7 +374,3 @@ lucas_chk(high_n, quiet)
return 0; return 0;
} }
} }
if (config("lib_debug") >= 0) {
print "lucas_chk(high_n) defined";
}

View File

@@ -31,7 +31,3 @@ define mersenne(p)
/* 2^p-1 is prime iff u(p) = 0 mod 2^p-1 */ /* 2^p-1 is prime iff u(p) = 0 mod 2^p-1 */
return (u == 0); return (u == 0);
} }
if (config("lib_debug") >= 0) {
print "mersenne(p) defined";
}

View File

@@ -12,12 +12,12 @@ obj mod {a}; /* definition of the object */
global mod_value = 100; /* modulus value (value of N) */ global mod_value = 100; /* modulus value (value of N) */
define mod(a) define lmod(a)
{ {
local obj mod x; local obj mod x;
if (!isreal(a) || !isint(a)) if (!isreal(a) || !isint(a))
quit "Bad argument for mod function"; quit "Bad argument for lmod function";
x.a = a % mod_value; x.a = a % mod_value;
return x; return x;
} }
@@ -34,7 +34,7 @@ define mod_print(a)
define mod_one() define mod_one()
{ {
return mod(1); return lmod(1);
} }
@@ -51,9 +51,9 @@ define mod_cmp(a, b)
define mod_rel(a, b) define mod_rel(a, b)
{ {
if (isnum(a)) if (isnum(a))
a = mod(a); a = lmod(a);
if (isnum(b)) if (isnum(b))
b = mod(b); b = lmod(b);
if (a.a < b.a) if (a.a < b.a)
return -1; return -1;
return a.a != b.a; return a.a != b.a;
@@ -163,9 +163,9 @@ define mod_div(a, b)
obj mod x, y; obj mod x, y;
if (isnum(a)) if (isnum(a))
a = mod(a); a = lmod(a);
if (isnum(b)) if (isnum(b))
b = mod(b); b = lmod(b);
c = gcd(a.a, b.a); c = gcd(a.a, b.a);
x.a = a.a / c; x.a = a.a / c;
y.a = b.a / c; y.a = b.a / c;
@@ -191,20 +191,6 @@ define mod_pow(a, b)
if (config("lib_debug") >= 0) { if (config("lib_debug") >= 0) {
print "obj mod {a} defined"; print "obj mod {a} defined";
print "mod(a) defined";
print "mod_print(a) defined";
print "mod_one(a) defined";
print "mod_cmp(a, b) defined";
print "mod_rel(a, b) defined";
print "mod_add(a, b) defined";
print "mod_sub(a, b) defined";
print "mod_mod(a, b) defined";
print "mod_square(a) defined";
print "mod_inc(a) defined";
print "mod_dec(a) defined";
print "mod_inv(a) defined";
print "mod_div(a, b) defined";
print "mod_pow(a, b) defined";
print "mod_value defined"; print "mod_value defined";
print "set mod_value as needed"; print "set mod_value as needed";
} }

View File

@@ -592,41 +592,3 @@ define set_print(a)
} }
local N, M; /* End scope of static variables N, M */ local N, M; /* End scope of static variables N, M */
if (config("lib_debug") >= 0) {
print "isset(a) defined";
print "setbound(n) defined";
print "empty() defined";
print "full() defined";
print "isin(a, b) defined";
print "addmember(a, n) defined";
print "rmmember(a, n) defined";
print "set() defined";
print "mkset(s) defined";
print "primes(a, b) defined";
print "set_max(a) defined";
print "set_min(a) defined";
print "set_not(a) defined";
print "set_cmp(a, b) defined";
print "set_rel(a, b) defined";
print "set_or(a, b) defined";
print "set_and(a, b) defined";
print "set_comp(a) defined";
print "set_setminus(a, b) defined";
print "set_xor(a,b) defined";
print "set_content(a) defined";
print "set_add(a, b) defined";
print "set_sub(a, b) defined";
print "set_mul(a, b) defined";
print "set_square(a) defined";
print "set_pow(a, n) defined";
print "set_sum(a) defined";
print "set_plus(a) defined";
print "interval(a, b) defined";
print "isinterval(a) defined";
print "set_mod(a, b) defined";
print "randset(n, a, b) defined";
print "polyvals(L, A) defined";
print "polyvals2(L, A, B) defined";
print "set_print(a) defined";
}

View File

@@ -66,8 +66,3 @@ define pellx(D)
} }
return Q1; return Q1;
} }
if (config("lib_debug") >= 0) {
print "pell(D) defined";
print "pellx(D) defined";
}

View File

@@ -47,7 +47,3 @@ define qpi(epsilon)
} }
return (bround(1/an, bits)); return (bround(1/an, bits));
} }
if (config("lib_debug") >= 0) {
print "qpi(epsilon) defined";
}

View File

@@ -38,7 +38,3 @@ define pi_of_x(x)
} }
return primes; return primes;
} }
if (config("lib_debug") >= 0) {
print "pi_of_x(x) defined";
}

View File

@@ -6,7 +6,7 @@
* Factor using Pollard's p-1 method. * Factor using Pollard's p-1 method.
*/ */
define factor(N, B, ai, af) define pfactor(N, B, ai, af)
{ {
local a, k, i, d; local a, k, i, d;
@@ -28,7 +28,3 @@ define factor(N, B, ai, af)
} }
return 1; return 1;
} }
if (config("lib_debug") >= 0) {
print "factor(N, B, ai, af) defined";
}

View File

@@ -689,39 +689,4 @@ c=pol(1+2i,3+4i,5+6i);
if (config("lib_debug") >= 0) { if (config("lib_debug") >= 0) {
print "obj poly {p} defined"; print "obj poly {p} defined";
print "pol() defined";
print "poly_print(a) defined";
print "poly_add(a, b) defined";
print "poly_sub(a, b) defined";
print "poly_mul(a, b) defined";
print "poly_div(a, b) defined";
print "poly_quo(a,b) defined";
print "poly_mod(a,b) defined";
print "poly_neg(a) defined";
print "poly_conj(a) defined";
print "poly_cmp(a,b) defined";
print "iszero(a) defined";
print "plist(a) defined";
print "listmul(a,b) defined";
print "ev(a,t) defined";
print "evp(s,t) defined";
print "ispoly(a) defined";
print "isstring(a) defined";
print "var(name) defined";
print "pcoeff(a) defined";
print "pterm(a,n) defined";
print "deg(a) defined";
print "polydiv(a,b) defined";
print "D(a,n) defined";
print "Dp(a,n) defined";
print "pgcd(a,b) defined";
print "plcm(a,b) defined";
print "monic(a) defined";
print "pfgcd(a,b) defined";
print "interp(X,Y,x) defined";
print "makediffs(X,Y) defined";
print "evalfd(T,x) defined";
print "mdet(A) defined";
print "M(A,n,I,J) defined";
print "mprint(A) defined";
} }

View File

@@ -94,8 +94,3 @@ define showvalues(str) {
print "\t":eval(str); print "\t":eval(str);
} }
} }
if (config("lib_debug") >= 0) {
print "adder() defined";
print "showvalues(str) defined";
}

View File

@@ -48,8 +48,3 @@ define psqrt(u, p)
} }
return min(v, p - v); return min(v, p - v);
} }
if (config("lib_debug") >= 0) {
print "psqrt(u, p) defined";
}

60
lib/qtime.cal Normal file
View File

@@ -0,0 +1,60 @@
/*
* qtime - Display time as English sentence
*
* usage:
* qtime(utc_hr_offset)
*
* utc_hr_offset Offset from UTC in hours.
*
* Written by: Klaus Alexander Seistrup <kseis@magnetic-ink.dk>
* With minor mods by: Landon Curt Noll <chongo@toad.com>
*
* See:
* http://www.magnetic-ink.dk/download/qtime.html
*
* for examples of qtime() written on other languages.
*/
/*
* qtime - Display time as English sentence
*/
define qtime(utc_hr_offset)
{
static mat hr[12] = {
"twelve", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven"
};
static mat mn[7] = {
"", "five ", "ten ", "a quarter ", "twenty ", "twenty-five ", "half "
};
static mat ny[5] = {
"nearly ", "almost ", "", "just after ", "after "
};
static mat up[3] = {
"to ", "", "past "
};
local adj_mins = (((time() + utc_hr_offset*3600) % 86400) + 30) // 60 + 27;
local hours = (adj_mins // 60) % 12;
local minutes = adj_mins % 60;
local almost = minutes % 5;
local divisions = (minutes // 5) - 5;
local to_past_idx = divisions > 0 ? 1 : 0;
if (divisions < 0) {
divisions = -divisions;
to_past_idx = -1;
}
++to_past_idx;
/*
* Print the English sentence
*
* We avoid forward and back quotes just to show that the char()
* builtin function can be used in conjunction with a printf.
*/
printf("It%cs %s%s%s%s",
char(0x27), ny[almost], mn[divisions], up[to_past_idx], hr[hours]);
if (divisions == 0)
printf(" o%cclock", char(0x27));
printf (".\n");
}

View File

@@ -197,19 +197,4 @@ define quat_shift(a, b)
if (config("lib_debug") >= 0) { if (config("lib_debug") >= 0) {
print "obj quat {s, v} defined"; print "obj quat {s, v} defined";
print "quat(a, b, c, d) defined";
print "quat_print(a) defined";
print "quat_norm(a) defined";
print "quat_abs(a, e) defined";
print "quat_conj(a) defined";
print "quat_add(a, e) defined";
print "quat_sub(a, e) defined";
print "quat_inc(a) defined";
print "quat_dec(a) defined";
print "quat_neg(a) defined";
print "quat_mul(a, b) defined";
print "quat_div(a, b) defined";
print "quat_inv(a) defined";
print "quat_scale(a, b) defined";
print "quat_shift(a, b) defined";
} }

View File

@@ -112,7 +112,3 @@ define randbitrun(run_cnt)
printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt); printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt);
printf("max length=%d\n", max_run); printf("max length=%d\n", max_run);
} }
if (config("lib_debug") >= 0) {
print "randbitrun([run_length]) defined";
}

View File

@@ -129,7 +129,3 @@ randmprime(bits, seed, dbg)
} }
return ret; return ret;
} }
if (config("lib_debug") >= 0) {
print "randmprime(bits, seed [,dbg]) defined";
}

View File

@@ -112,7 +112,3 @@ define randombitrun(run_cnt)
printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt); printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt);
printf("max length=%d\n", max_run); printf("max length=%d\n", max_run);
} }
if (config("lib_debug") >= 0) {
print "randombitrun([run_length]) defined";
}

View File

@@ -121,7 +121,3 @@ define randomrun(run_cnt)
printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt); printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt);
printf("max length=%d\n", max_run); printf("max length=%d\n", max_run);
} }
if (config("lib_debug") >= 0) {
print "randomrun([run_length]) defined";
}

View File

@@ -22,13 +22,13 @@ prob = 0; /* clear problem counter */
global junk; /* throw away value */ global junk; /* throw away value */
junk = errcount(0); /* clear error count */ junk = errcount(0); /* clear error count */
junk = errmax(0x7fffffff); /* set maximum error very high */ junk = errmax(-1); /* prevent errcount from abouting */
global ecnt; /* expected value of errcount() */ global ecnt; /* expected value of errcount() */
ecnt = 0; /* clear expected errcount() value */ ecnt = 0; /* clear expected errcount() value */
initcfg = config("all", "oldstd"); /* set config to startup default */ initcfg = config("all", "oldstd"); /* set config to startup default */
initcfg = config("lib_debug", -1); /* disable lib startup messages */ initcfg = config("lib_debug", -4); /* disable lib startup messages */
initcfg = config("calc_debug", 1); /* enable more internal debugging */ initcfg = config("calc_debug", 1); /* enable more internal debugging */
initcfg = config("all"); /* save state for later use */ initcfg = config("all"); /* save state for later use */
@@ -702,6 +702,8 @@ define test_functions()
{ {
local a, b; local a, b;
local pi; local pi;
local h, n, r, m, v;
local n2, m2, v2;
print '700: Beginning test_functions'; print '700: Beginning test_functions';
@@ -1163,7 +1165,31 @@ define test_functions()
vrfy(popcnt(pi(1e-20),0) == 69, '1101: popcnt(pi(1e-20),0) == 69'); vrfy(popcnt(pi(1e-20),0) == 69, '1101: popcnt(pi(1e-20),0) == 69');
vrfy(popcnt(17^777) == 1593, '1102: popcnt(17^777) == 1593'); vrfy(popcnt(17^777) == 1593, '1102: popcnt(17^777) == 1593');
print '1103: Ending test_functions'; /*
* more hnrmod testing
*/
vrfy(hnrmod(21<<100+5,3,100,1) == (21<<100+5)%(3<<100+1),
'1103: hnrmod(21<<100+5,3,100,1) == (21<<100+5)%(3<<100+1)');
vrfy(hnrmod(21<<500+7,3,500,1) == (21<<500+7)%(3<<500+1),
'1104: hnrmod(21<<500+7,3,500,1) == (21<<500+7)%(3<<500+1)');
vrfy(hnrmod(-767256,84,1,0) == (-767256)%(84<<1+0),
'1105: hnrmod(-767256,84,1,0) == (-767256)%(84<<1+0)');
vrfy(hnrmod(-831150,75,1,0) == (-831150)%(75<<1+0),
'1106: hnrmod(-831150,75,1,0) == (-831150)%(75<<1+0)');
vrfy(hnrmod(-767256,84,1,1) == (-767256)%(84<<1+1),
'1107: hnrmod(-767256,84,1,1) == (-767256)%(84<<1+1)');
vrfy(hnrmod(-831150,75,1,1) == (-831150)%(75<<1+1),
'1108: hnrmod(-831150,75,1,1) == (-831150)%(75<<1+1)');
vrfy(hnrmod(-767256,84,1,-1) == (-767256)%(84<<1-1),
'1109: hnrmod(-767256,84,1,-1) == (-767256)%(84<<1-1)');
vrfy(hnrmod(-831150,75,1,-1) == (-831150)%(75<<1-1),
'1110: hnrmod(-831150,75,1,-1) == (-831150)%(75<<1-1)');
vrfy(hnrmod(21<<100+5,3,100,0) == (21<<100+5)%(3<<100+0),
'1111: hnrmod(21<<100+5,3,100,0) == (21<<100+5)%(3<<100+0)');
vrfy(hnrmod(21<<500+7,3,500,-1) == (21<<500+7)%(3<<500-1),
'1112: hnrmod(21<<500+7,3,500,-1) == (21<<500+7)%(3<<500-1)');
print '1113: Ending test_functions';
} }
print '017: parsed test_functions()'; print '017: parsed test_functions()';
@@ -1529,7 +1555,12 @@ define test_rand()
vrfy(randbit() == 1, '1567: randbit() == 1'); vrfy(randbit() == 1, '1567: randbit() == 1');
vrfy(randbit() == 0, '1568: randbit() == 0'); vrfy(randbit() == 0, '1568: randbit() == 0');
print '1569: Ending rand test'; /* test seed() as best as we can */
vrfy(seed() >= 0, '1569: seed() >= 0');
vrfy(seed() < 2^64, '1570: seed() < 2^64');
vrfy(isrand(srand(seed())), '1571: isrand(srand(seed()))');
print '1572: Ending rand test';
} }
print '025: parsed test_rand()'; print '025: parsed test_rand()';
@@ -4384,7 +4415,12 @@ define test_random()
vrfy(randombit(123) == 0x2058f802dd42b3aee4e734eacc13057, \ vrfy(randombit(123) == 0x2058f802dd42b3aee4e734eacc13057, \
'5463: randombit(123) == 0x2058f802dd42b3aee4e734eacc13057'); '5463: randombit(123) == 0x2058f802dd42b3aee4e734eacc13057');
print '5464: Ending test_random'; /* test seed() as best as we can */
vrfy(seed() >= 0, '5464: seed() >= 0');
vrfy(seed() < 2^64, '5465: seed() < 2^64');
vrfy(israndom(srandom(seed())), '5466: israndom(srandom(seed()))');
print '5467: Ending test_random';
} }
print '137: parsed test_random()'; print '137: parsed test_random()';
@@ -5881,8 +5917,10 @@ define test_is()
*/ */
blkfree("blk5900"); blkfree("blk5900");
print '6663: blkfree("blk5900")'; print '6663: blkfree("blk5900")';
fclose(ofd);
print '6664: fclose(ofd)';
print '6664: Ending test_is'; print '6665: Ending test_is';
} }
print '168: test_is()'; print '168: test_is()';
@@ -6972,7 +7010,7 @@ define test_bigcomb()
{ {
local a, b, n, i, v1, v2; local a, b, n, i, v1, v2;
print '7900: Starting test_bigcomb()'; print '7900: Starting test_bigcomb';
a = 1234/4321; a = 1234/4321;
print '7901: a = 1234/4321'; print '7901: a = 1234/4321';
b = 3456/6543; b = 3456/6543;
@@ -6995,7 +7033,7 @@ define test_bigcomb()
vrfy(f7900(-7/4,33/4,-2) == g7900(-7/4,33/4,-2), vrfy(f7900(-7/4,33/4,-2) == g7900(-7/4,33/4,-2),
'7913: f7900(-7/4,33/4,-2) == g7900(-7/4,33/4,-2)'); '7913: f7900(-7/4,33/4,-2) == g7900(-7/4,33/4,-2)');
print '7914: Ending test_bigcomb()'; print '7914: Ending test_bigcomb';
} }
print '186: parsed test_bigcomb()'; print '186: parsed test_bigcomb()';
@@ -7010,7 +7048,7 @@ define test_natnumset()
{ {
local A, B, C, D, P, P1, L1, L2; local A, B, C, D, P, P1, L1, L2;
print '8000: Starting test_natnumset()'; print '8000: Starting test_natnumset';
A = set(17, 2, 0, 24, 2); A = set(17, 2, 0, 24, 2);
print '8101: A = set(17, 2, 0, 24, 2);'; print '8101: A = set(17, 2, 0, 24, 2);';
@@ -7067,7 +7105,7 @@ define test_natnumset()
vrfy(polyvals2(L2,C,D) == set(12,16,21,27,45,55,77,91), vrfy(polyvals2(L2,C,D) == set(12,16,21,27,45,55,77,91),
'8135: polyvals(L2,C,D) == set(12,16,21,27,45,55,77,91)'); '8135: polyvals(L2,C,D) == set(12,16,21,27,45,55,77,91)');
print '8136: Ending test_natnumset()'; print '8136: Ending test_natnumset';
} }
print '188: parsed test_natnumset()'; print '188: parsed test_natnumset()';
@@ -7077,7 +7115,7 @@ print '188: parsed test_natnumset()';
*/ */
define test_somenew() define test_somenew()
{ {
print '8200: Starting test_somenew()'; print '8200: Starting test_somenew';
vrfy(char(-1) == char(255), '8201: char(-1) == char(255)'); vrfy(char(-1) == char(255), '8201: char(-1) == char(255)');
vrfy(char(258) == char(2), '8202: char(258) == char(2)'); vrfy(char(258) == char(2), '8202: char(258) == char(2)');
@@ -7101,7 +7139,7 @@ define test_somenew()
vrfy(1/(1/0) == 0, '8215: 1/(1/0) == 0'); vrfy(1/(1/0) == 0, '8215: 1/(1/0) == 0');
vrfy(inverse(1/0) == 0, '8216: inverse(1/0) == 0'); vrfy(inverse(1/0) == 0, '8216: inverse(1/0) == 0');
print '8217: Ending test_somenew()'; print '8217: Ending test_somenew';
} }
print '189: parsed test_somenew()'; print '189: parsed test_somenew()';
@@ -7118,7 +7156,7 @@ print '200: Reserved for top level test use';
define count_errors() define count_errors()
{ {
if (prob == 0) { if (prob == 0) {
print "9998: passed all tests /\\../\\"; print "9997: passed all tests /\\../\\";
} else { } else {
print "****", prob, "error(s) found \\/++\\/"; print "****", prob, "error(s) found \\/++\\/";
} }
@@ -7354,6 +7392,96 @@ return test_natnumset();
print; print;
return test_somenew(); return test_somenew();
/*
* read various calc libs
*
* We read most of the calc libs shipped with the distribution.
* There are a few lib files that are not read:
*
* beer.cal - prints a bunch of things when loaded
* hello.cal - designed to go into an infinite loop
* lucal.cal - already read by this file
* lucas_chk.cal - already read by this file
* lucas_tbl.cal - duplicatres code already read by another file
* regress.cal - this file
* surd.cal - already read by this file
* testXXXX.cal - already read by this file
* xx_print.cal - prints a bunch of things when loaded
*
* We want to do this 2nd to last; ahead of any final cleanup and behind
* all of real actions of regress.cal.
*/
print; print;
print '9800: Starting read of selected calc libs';
read -once bernoulli;
print '9801: read -once bernoulli';
read -once bigprime;
print '9802: read -once bigprime';
read -once chrem;
print '9803: read -once chrem';
read -once deg;
print '9804: read -once deg';
read -once ellip;
print '9805: read -once ellip';
read -once mersenne;
print '9806: read -once mersenne';
read -once mfactor;
print '9807: read -once mfactor';
read -once mod;
print '9808: read -once mod';
read -once natnumset;
print '9809: read -once natnumset';
read -once pell;
print '9810: read -once pell';
read -once pi;
print '9811: read -once pi';
read -once pix;
print '9812: read -once pix';
read -once pollard;
print '9813: read -once pollard';
read -once poly;
print '9814: read -once poly';
read -once prompt;
print '9815: read -once prompt';
read -once psqrt;
print '9816: read -once psqrt';
read -once quat;
print '9817: read -once quat';
read -once randbitrun;
print '9818: read -once randbitrun';
read -once randmprime;
print '9819: read -once randmprime';
read -once randombitrun;
print '9820: read -once randombitrun';
read -once randomrun;
print '9821: read -once randomrun';
read -once randrun;
print '9822: read -once randrun';
read -once seedrandom;
print '9823: read -once seedrandom';
read -once solve;
print '9824: read -once solve';
read -once sumsq;
print '9825: read -once sumsq';
read -once unitfrac;
print '9826: read -once unitfrac';
read -once varargs;
print '9827: read -once varargs';
read -once qtime;
print '9828: read -once qtime';
print '9829: Ending read of selected calc libs';
/*
* cleanup and report the results
*/
print;
freeredc();
print '9995: freeredc()';
freestatics();
print '9996: freestatics()';
return count_errors(); return count_errors();
freeglobals();
print '9998: freeglobals()';
print '9999: Ending regression tests'; print '9999: Ending regression tests';

View File

@@ -41,7 +41,3 @@ define solve(low, high, epsilon)
} }
} }
} }
if (config("lib_debug") >= 0) {
print "solve(low, high, epsilon) defined";
}

View File

@@ -37,7 +37,3 @@ define ss(p)
} }
print a : "^2 +" , b : "^2 =" , a^2 + b^2; print a : "^2 +" , b : "^2 =" , a^2 + b^2;
} }
if (config("lib_debug") >= 0) {
print "ss(p) defined";
}

View File

@@ -263,25 +263,6 @@ define surd_rel(a, b)
if (config("lib_debug") >= 0) { if (config("lib_debug") >= 0) {
print "obj surd {a, b} defined"; print "obj surd {a, b} defined";
print "surd(a, b) defined";
print "surd_print(a) defined";
print "surd_conj(a) defined";
print "surd_norm(a) defined";
print "surd_value(a, xepsilon) defined";
print "surd_add(a, b) defined";
print "surd_sub(a, b) defined";
print "surd_inc(a) defined";
print "surd_dec(a) defined";
print "surd_neg(a) defined";
print "surd_mul(a, b) defined";
print "surd_square(a) defined";
print "surd_scale(a, b) defined";
print "surd_shift(a, b) defined";
print "surd_div(a, b) defined";
print "surd_inv(a) defined";
print "surd_sgn(a) defined";
print "surd_cmp(a, b) defined";
print "surd_rel(a, b) defined";
print "surd_type defined"; print "surd_type defined";
print "set surd_type as needed"; print "set surd_type as needed";
} }

View File

@@ -10,7 +10,3 @@
*/ */
++value; ++value;
if (config("lib_debug") >= 0) {
/* nothing to do */
}

View File

@@ -95,7 +95,3 @@ define ckmat()
/* args match the matrix in the object */ /* args match the matrix in the object */
return 1; return 1;
} }
if (config("lib_debug") >= 0) {
/* nothing to do */
}

View File

@@ -491,25 +491,3 @@ define test2600(verbose, tnum)
} }
return tnum; return tnum;
} }
if (config("lib_debug") >= 0) {
print "global defaultverbose defined";
print "global err defined";
print "testismult(str,n,verbose) defined";
print "testsqrt(str,n,eps,verbose) defined";
print "testexp(str,n,eps,verbose) defined";
print "testln(str,n,eps,verbose) defined";
print "testpower(str,n,b,eps,verbose) defined";
print "testgcd(str,n,verbose) defined";
print "cpow(x,n,eps) defined";
print "cexp(x,eps) defined";
print "cln(x,eps) defined";
print "mkreal() defined";
print "mkcomplex() defined";
print "mkbigreal() defined";
print "mksmallreal() defined";
print "testappr(str,n,verbose) defined";
print "checkappr(x,y,z,verbose) defined";
print "checkresult(x,y,z,a) defined";
print "test2600(verbose,tnum) defined";
}

View File

@@ -308,23 +308,3 @@ define test2700(verbose, tnum)
} }
return tnum; return tnum;
} }
if (config("lib_debug") >= 0) {
print "global defaultverbose defined";
print "global err defined";
print "mknonnegreal() defined";
print "mkposreal() defined";
print "mkreal_2700() defined";
print "mknonzeroreal() defined";
print "mkposfrac() defined";
print "mkfrac() defined";
print "mksquarereal() defined";
print "mknonsquarereal() defined";
print "mkcomplex_2700() defined";
print "testcsqrt(str,n,verbose) defined";
print "checksqrt(x,y,z,v) defined";
print "checkavrem(A,B,X,eps) defined";
print "checkrounding(s,n,t,u,z) defined";
print "iscomsq(x) defined";
print "test2700(verbose,tnum) defined";
}

View File

@@ -17,14 +17,3 @@ define res_mul(a,b) {local obj res v = {(a.r * b.r) % md}; return v;};
define res_neg(a) {local obj res v = {(-a.r) % md}; return v;}; define res_neg(a) {local obj res v = {(-a.r) % md}; return v;};
define res_inv(a) {local obj res v = {minv(a.r, md)}; return v;}; define res_inv(a) {local obj res v = {minv(a.r, md)}; return v;};
define res(x) {local obj res v = {x % md}; return v;}; define res(x) {local obj res v = {x % md}; return v;};
if (config("lib_debug") >= 0) {
print "obj res defined";
print "global md defined";
print "res_test(a) defined";
print "res_sub(a, b) defined";
print "res_mul(a, b) defined";
print "res_neg(a) defined";
print "res_inv(a) defined";
print "res(x) defined";
}

View File

@@ -122,11 +122,3 @@ define test3300(verbose, tnum)
} }
return tnum; return tnum;
} }
if (config("lib_debug") >= 0) {
print "global defaultverbose defined";
print "global err defined";
print "testi(str, n, N, verbose) defined";
print "testr(str, n, N, verbose) defined";
print "test3300(verbose, tnum) defined";
}

View File

@@ -299,15 +299,3 @@ define test3400(verbose, tnum)
} }
return tnum; return tnum;
} }
if (config("lib_debug") >= 0) {
print "global defaultverbose defined";
print "global err defined";
print "test3401(str, n, eps, verbose) defined";
print "test3402(str, n, eps, verbose) defined";
print "test3403(str, n, eps, verbose) defined";
print "test3404(str, n, eps, verbose) defined";
print "test3405(str, n, eps, verbose) defined";
print "test3406(str, n, eps, verbose) defined";
print "test3400(verbose, tnum) defined";
}

View File

@@ -272,14 +272,3 @@ define test3500(verbose, tnum, n, N)
} }
return tnum; return tnum;
} }
if (config("lib_debug") >= 0) {
print "global defaultverbose defined";
print "global err defined";
print "testfrem(x, y, verbose) defined";
print "testgcdrem(x, y, verbose) defined";
print "testf(str, n, verbose) defined";
print "testg(str, n, verbose) defined";
print "testh(str, n, N, verbose) defined";
print "test3500(verbose, n, N) defined";
}

View File

@@ -452,32 +452,3 @@ define test4000(v, tnum)
} }
return tnum; return tnum;
} }
if (config("lib_debug") >= 0) {
print "global defaultverbose";
print "global err";
print "global BASEB";
print "global BASE";
print "global COUNT";
print "global SKIP";
print "global RESIDUE";
print "global MODULUS";
print "global K1";
print "global H1";
print "global K2";
print "global H2";
print "global K3";
print "global H3";
print "plen(N) defined";
print "clen(N) defined";
print "ptimes(str, N, n, count, skip, verbose) defined";
print "ctimes(str, N, n, count, skip, verbose) defined";
print "crtimes(str, a, b, n, count, skip, verbose) defined";
print "ntimes(str, N, n, count, skip, residue, mod, verbose) defined";
print "testnextcand(str, N, n, cnt, skip, res, mod, verbose) defined";
print "testnext1(x, y, count, skip, residue, modulus) defined";;
print "testprevcand(str, N, n, cnt, skip, res, mod, verbose) defined";
print "testprev1(x, y, count, skip, residue, modulus) defined";
print "test4000(verbose, tnum) defined";
}

View File

@@ -472,20 +472,3 @@ define test4100(v, tnum)
} }
return tnum; return tnum;
} }
if (config("lib_debug") >= 0) {
print "global defaultverbose";
print "global err";
print "global K1";
print "global K2";
print "global BASEB";
print "global BASE";
print "rlen_4100(N) defined";
print "olen(N) defined";
print "test4101(x, y, m, k, z1, z2) defined";
print "testall(str, n, N, M, verbose) defined";
print "times(str, N, n, verbose) defined";
print "powtimes(str, N1, N2, n, verbose) defined";
print "inittimes(str, N, n, verbose) defined";
print "test4100(verbose, tnum) defined";
}

View File

@@ -223,6 +223,11 @@ define ttest(str, m, n, verbose)
return 1; return 1;
} }
} }
if (iserror(fclose(f))) {
print 'failed';
printf("**** Failure 6 for i = %d\n", i);
return 1;
}
i = rm("junk4600"); i = rm("junk4600");
if (verbose > 0) { if (verbose > 0) {
printf("passed\n"); printf("passed\n");
@@ -299,12 +304,3 @@ define test4600(v, tnum)
} }
return tnum; return tnum;
} }
if (config("lib_debug") >= 0) {
print "stest(str [, verbose]) defined";
print "ttest([m, [n [,verbose]]]) defined";
print "sprint(x) defined";
print "findline(f,s) defined";
print "findlineold(f,s) defined";
print "test4600(verbose, tnum) defined";
}

View File

@@ -48,9 +48,3 @@ define test5100(x)
} }
global a5100 = a5100, b5100 = b5100; global a5100 = a5100, b5100 = b5100;
} }
if (config("lib_debug") >= 0) {
print "global a5100";
print "global b5100";
print "test5100(x) defined";
}

View File

@@ -30,11 +30,3 @@ static a5200 = 20;
define f5200(x) = a5200 + x; define f5200(x) = a5200 + x;
define g5200(x) {global a5200 = 30; return a5200 + x;} define g5200(x) {global a5200 = 30; return a5200 + x;}
define h5200(x) = a5200 + x; define h5200(x) = a5200 + x;
if (config("lib_debug") >= 0) {
print "global a5200";
print "static a5200";
print "f5200(x) defined";
print "g5200(x) defined";
print "h5200(x) defined";
}

View File

@@ -27,8 +27,3 @@ define unitfrac(x)
} while ((num(x) > 1) || (x == di) || (x == 1)); } while ((num(x) > 1) || (x == di) || (x == 1));
print ' [1/1]',, x; print ' [1/1]',, x;
} }
if (config("lib_debug") >= 0) {
print "unitfrac(x) defined";
}

View File

@@ -21,7 +21,7 @@ print "global blkmax defined, assigned value 8";
print; print;
B = blk(); B = blk();
define isoctet(a) = istype(a, B[0]); define is_octet(a) = istype(a, B[0]);
define list_print(a) { define list_print(a) {
local i; local i;
@@ -131,7 +131,7 @@ define strchar(a) {
if (isstr(a)) if (isstr(a))
a = ord(a); a = ord(a);
else if (isoctet(a)) else if (is_octet(a))
a = a; /* This converts octet to number */ a = a; /* This converts octet to number */
else if (!isint(a) || a < 0 || a > 255) else if (!isint(a) || a < 0 || a > 255)
@@ -269,15 +269,3 @@ define octet_print(a) {
print "Here is the earlier block with a new octet_print()"; print "Here is the earlier block with a new octet_print()";
print B1; print B1;
print; print;
if (config("lib_debug") >= 0) {
print "isoctet(a) defined";
print "list_print(a) defined";
print "mat_print (a) defined";
print "octet_print(a) defined";
print "blk_print(a) defined";
print "nblk_print (a) defined";
print "strchar(a) defined";
print "file_print(a) defined";
print "error_print(a) defined";
}

View File

@@ -63,9 +63,9 @@ int new_std = FALSE; /* TRUE (-n) => use newstd configuration */
int abortlevel; /* current level of aborts */ int abortlevel; /* current level of aborts */
BOOL inputwait; /* TRUE if in a terminal input wait */ BOOL inputwait; /* TRUE if in a terminal input wait */
jmp_buf jmpbuf; /* for errors */ jmp_buf jmpbuf; /* for errors */
int start_done = FALSE; /* TRUE => start up processing finished */ run run_state = RUN_UNKNOWN; /* calc startup and run state */
char *program = "calc"; /* our name */ char *program = "calc"; /* our name */
char cmdbuf[MAXCMD+1]; /* command line expression */ char cmdbuf[MAXCMD+1+1+1]; /* command line expression + "\n\0" + guard */
/* /*
@@ -82,7 +82,9 @@ int allow_exec = TRUE; /* FALSE => may not execute any commands */
int p_flag = FALSE; /* TRUE => pipe mode */ int p_flag = FALSE; /* TRUE => pipe mode */
int q_flag = FALSE; /* TRUE => don't execute rc files */ int q_flag = FALSE; /* TRUE => don't execute rc files */
int u_flag = FALSE; /* TRUE => unbuffer stdin and stdout */ int u_flag = FALSE; /* TRUE => unbuffer stdin and stdout */
int d_flag = FALSE; /* TRUE => disable heading, lib_debug == 0 */
int c_flag = FALSE; /* TRUE => continue on error if permitted */
int i_flag = FALSE; /* TRUE => go interactive if permitted */
/* /*
* global values * global values
@@ -94,10 +96,12 @@ char *home; /* $HOME or default */
char *pager; /* $PAGER or default */ char *pager; /* $PAGER or default */
char *shell; /* $SHELL or default */ char *shell; /* $SHELL or default */
int stdin_tty = FALSE; /* TRUE if stdin is a tty */ int stdin_tty = FALSE; /* TRUE if stdin is a tty */
int post_init = FALSE; /* TRUE setjmp for math_error is readready */ int havecommands = FALSE; /* TRUE if have one or more cmd args */
int stoponerror = FALSE; /* >0 => stop, <0 => continue on error */
int post_init = FALSE; /* TRUE setjmp for math_error is ready */
int no_env = FALSE; /* TRUE (-e) => ignore env vars on startup */ int no_env = FALSE; /* TRUE (-e) => ignore env vars on startup */
int ign_errmax = FALSE; /* TRUE (-i) => ignore when errcount exceeds errmax */ int errmax = ERRMAX; /* if >= 0, maximum value for errcount */
NUMBER *epsilon_default; /* default allowed error for float calcs */ NUMBER *epsilon_default; /* default allowed error for float calcs */
@@ -154,6 +158,20 @@ libcalc_call_me_first(void)
conf = config_copy(&oldstd); conf = config_copy(&oldstd);
} }
/*
* -d turns off lib_debug
*/
if (d_flag) {
conf->lib_debug = 0;
}
/*
* -p turns off tab
*/
if (p_flag) {
conf->tab_ok = 0;
}
/* /*
* initialize * initialize
*/ */
@@ -162,6 +180,7 @@ libcalc_call_me_first(void)
/* /*
* ready to rock & roll .. * ready to rock & roll ..
*/ */
run_state = RUN_PRE_BEGIN;
init_done = 1; init_done = 1;
return; return;
} }
@@ -228,10 +247,6 @@ reinitialize(void)
math_setfp(stdout); math_setfp(stdout);
resetscopes(); resetscopes();
resetinput(); resetinput();
if (q_flag == FALSE && allow_read) {
q_flag = TRUE;
runrcfiles();
}
(void) openterminal(); (void) openterminal();
} }
@@ -281,6 +296,11 @@ initenv(void)
if (calcrc == NULL) { if (calcrc == NULL) {
calcrc = DEFAULTCALCRC; calcrc = DEFAULTCALCRC;
} }
if (strlen(calcrc) > MAX_CALCRC) {
math_error("The $CALCRC variable is longer than %d chars",
MAX_CALCRC);
/*NOTREACHED*/
}
/* determine the $CALCBINDINGS value */ /* determine the $CALCBINDINGS value */
calcbindings = (no_env ? NULL : getenv(CALCBINDINGS)); calcbindings = (no_env ? NULL : getenv(CALCBINDINGS));

View File

@@ -206,7 +206,7 @@ main(int argc, char **argv)
'/', "* signed 64 bits *", '/'); '/', "* signed 64 bits *", '/');
putchar('\n'); putchar('\n');
printf("%c%s%c\n", '/',"* how to form 64 bit constants *",'/'); printf("%c%s%c\n", '/',"* how to form 64 bit constants *",'/');
#if defined(__STDC__) && __STDC__ != 0 #if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
printf("#define U(x) x ## ULL\n"); printf("#define U(x) x ## ULL\n");
printf("#define L(x) x ## LL\n"); printf("#define L(x) x ## LL\n");
#else #else
@@ -322,7 +322,7 @@ main(int argc, char **argv)
'/', "* signed 64 bits *", '/'); '/', "* signed 64 bits *", '/');
putchar('\n'); putchar('\n');
printf("%c%s%c\n", '/',"* how to form 64 bit constants *",'/'); printf("%c%s%c\n", '/',"* how to form 64 bit constants *",'/');
#if defined(__STDC__) && __STDC__ != 0 #if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
printf("#define U(x) x ## UL\n"); printf("#define U(x) x ## UL\n");
printf("#define L(x) x ## L\n"); printf("#define L(x) x ## L\n");
#else #else
@@ -341,7 +341,7 @@ main(int argc, char **argv)
'/', "* signed 64 bits *", '/'); '/', "* signed 64 bits *", '/');
putchar('\n'); putchar('\n');
printf("%c%s%c\n", '/',"* how to form 64 bit constants *",'/'); printf("%c%s%c\n", '/',"* how to form 64 bit constants *",'/');
#if defined(__STDC__) && __STDC__ != 0 #if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
printf("#define U(x) x ## ULL\n"); printf("#define U(x) x ## ULL\n");
printf("#define L(x) x ## LL\n"); printf("#define L(x) x ## LL\n");
#else #else

View File

@@ -32,7 +32,6 @@ static VALUE oldvalue; /* previous calculation value */
static BOOL saveval = TRUE; /* to enable or disable saving */ static BOOL saveval = TRUE; /* to enable or disable saving */
static int calc_errno; /* most recent error-number */ static int calc_errno; /* most recent error-number */
static int errcount; /* counts calls to error_value */ static int errcount; /* counts calls to error_value */
static int errmax = ERRMAX; /* maximum for errcount without abort */
static BOOL go; static BOOL go;
/* /*
@@ -640,9 +639,8 @@ o_elemaddr(FUNC *fp, long index)
math_error("Non-existent element for matrix"); math_error("Non-existent element for matrix");
/*NOTREACHED*/ /*NOTREACHED*/
} }
stack->v_type = V_ADDR; vp = &mp->m_table[index];
stack->v_addr = &mp->m_table[index]; break;
return;
case V_OBJ: case V_OBJ:
op = vp->v_obj; op = vp->v_obj;
offset = objoffset(op, index); offset = objoffset(op, index);
@@ -650,13 +648,21 @@ o_elemaddr(FUNC *fp, long index)
math_error("Non-existent element for object"); math_error("Non-existent element for object");
/*NOTREACHED*/ /*NOTREACHED*/
} }
stack->v_type = V_ADDR; vp = &op->o_table[offset];
stack->v_addr = &op->o_table[offset]; break;
return; case V_LIST:
vp = listfindex(vp->v_list, index);
if (vp == NULL) {
math_error("Index out of bounds for list");
/*NOTREACHED*/
}
break;
default: default:
math_error("Not indexing matrix or object"); math_error("Not initializing matrix, object or list");
/*NOTREACHED*/ /*NOTREACHED*/
} }
stack->v_type = V_ADDR;
stack->v_addr = vp;
} }
@@ -746,8 +752,10 @@ o_assign(void)
math_error("No-assign-from source for assign"); math_error("No-assign-from source for assign");
/*NOTREACHED*/ /*NOTREACHED*/
} }
tmp.v_subtype = V_NOSUBTYPE;
copyvalue(vp, &tmp); copyvalue(vp, &tmp);
} else if (vp->v_type == V_OCTET) { } else if (vp->v_type == V_OCTET) {
tmp.v_subtype = V_NOSUBTYPE;
copyvalue(vp, &tmp); copyvalue(vp, &tmp);
} else { } else {
tmp = *vp; tmp = *vp;
@@ -2458,7 +2466,7 @@ o_return(void)
/*ARGSUSED*/ /*ARGSUSED*/
static void static void
o_jumpeq(FUNC *fp, BOOL *dojump) o_jumpz(FUNC *fp, BOOL *dojump)
{ {
VALUE *vp; VALUE *vp;
int i; /* result of comparison */ int i; /* result of comparison */
@@ -2482,7 +2490,7 @@ o_jumpeq(FUNC *fp, BOOL *dojump)
/*ARGSUSED*/ /*ARGSUSED*/
static void static void
o_jumpne(FUNC *fp, BOOL *dojump) o_jumpnz(FUNC *fp, BOOL *dojump)
{ {
VALUE *vp; VALUE *vp;
int i; /* result of comparison */ int i; /* result of comparison */
@@ -2504,6 +2512,20 @@ o_jumpne(FUNC *fp, BOOL *dojump)
} }
/*
* jumpnn invokes a jump if top value points to a null value
*/
/*ARGSUSED*/
static void
o_jumpnn(FUNC *fp, BOOL *dojump)
{
if (stack->v_addr->v_type) {
*dojump = TRUE;
stack--;
}
}
/*ARGSUSED*/ /*ARGSUSED*/
static void static void
o_condorjump(FUNC *fp, BOOL *dojump) o_condorjump(FUNC *fp, BOOL *dojump)
@@ -3102,7 +3124,8 @@ o_quit(FUNC *fp, long index)
s = findstring(index); s = findstring(index);
cp = s->s_str; cp = s->s_str;
} }
if ((fp->f_name[0] == '*') && (fp->f_name[1] == '\0')) { if (inputisterminal() && (fp->f_name[0] == '*')
&& (fp->f_name[1] == '\0')) {
if (cp) if (cp)
printf("%s\n", cp); printf("%s\n", cp);
hist_term(); hist_term();
@@ -3117,6 +3140,8 @@ o_quit(FUNC *fp, long index)
printf("%s\n", cp); printf("%s\n", cp);
else else
printf("Quit statement executed\n"); printf("Quit statement executed\n");
if (!inputisterminal() && fp->f_name[0] == '*')
closeinput();
go = FALSE; go = FALSE;
} }
@@ -3234,7 +3259,7 @@ error_value(int e)
calc_errno = e; calc_errno = e;
if (e > 0) if (e > 0)
errcount++; errcount++;
if (errcount > errmax && !ign_errmax) { if (errmax >= 0 && errcount > errmax) {
math_error("Error %d caused errcount to exceed errmax", e); math_error("Error %d caused errcount to exceed errmax", e);
/*NOTREACHED*/ /*NOTREACHED*/
} }
@@ -3272,21 +3297,6 @@ set_errcount(int e)
} }
/*
* set_errno - return and set errno
*/
int
set_errmax(int e)
{
int res;
res = errmax;
if (e >= 0)
errmax = e;
return res;
}
/* /*
* Fill a newly created matrix at v1 with copies of value at v2. * Fill a newly created matrix at v1 with copies of value at v2.
*/ */
@@ -3418,8 +3428,8 @@ static struct opcode opcodes[MAX_OPCODE+1] = {
{o_duplicate, OPNUL, "DUPLICATE"}, /* duplicate top value */ {o_duplicate, OPNUL, "DUPLICATE"}, /* duplicate top value */
{o_pop, OPNUL, "POP"}, /* pop top value */ {o_pop, OPNUL, "POP"}, /* pop top value */
{o_return, OPRET, "RETURN"}, /* return value of function */ {o_return, OPRET, "RETURN"}, /* return value of function */
{o_jumpeq, OPJMP, "JUMPEQ"}, /* jump if value zero */ {o_jumpz, OPJMP, "JUMPZ"}, /* jump if value zero */
{o_jumpne, OPJMP, "JUMPNE"}, /* jump if value nonzero */ {o_jumpnz, OPJMP, "JUMPNZ"}, /* jump if value nonzero */
{o_jump, OPJMP, "JUMP"}, /* jump unconditionally */ {o_jump, OPJMP, "JUMP"}, /* jump unconditionally */
{o_usercall, OPTWO, "USERCALL"}, /* call a user function */ {o_usercall, OPTWO, "USERCALL"}, /* call a user function */
{o_getvalue, OPNUL, "GETVALUE"}, /* convert address to value */ {o_getvalue, OPNUL, "GETVALUE"}, /* convert address to value */
@@ -3522,7 +3532,8 @@ static struct opcode opcodes[MAX_OPCODE+1] = {
{o_hashop, OPNUL, "HASHOP"}, /* binary hash op */ {o_hashop, OPNUL, "HASHOP"}, /* binary hash op */
{o_backslash, OPNUL, "BACKSLASH"}, /* unary backslash op */ {o_backslash, OPNUL, "BACKSLASH"}, /* unary backslash op */
{o_setminus, OPNUL, "SETMINUS"}, /* binary backslash op */ {o_setminus, OPNUL, "SETMINUS"}, /* binary backslash op */
{o_plus, OPNUL, "PLUS"} /* unary + op */ {o_plus, OPNUL, "PLUS"}, /* unary + op */
{o_jumpnn, OPJMP, "JUMPNN"} /* jump if non-null */
}; };
@@ -3686,7 +3697,8 @@ calculate(FUNC *fp, int argcount)
freevalue(&locals[i]); freevalue(&locals[i]);
if (locals != localtable) if (locals != localtable)
free(locals); free(locals);
printf("\t\"%s\": line %ld\n", funcname, funcline); if (conf->calc_debug & 2)
printf("\t\"%s\": line %ld\n", funcname, funcline);
while (stack > beginstack) while (stack > beginstack)
freevalue(stack--); freevalue(stack--);
funcname = oldname; funcname = oldname;
@@ -3742,11 +3754,11 @@ dumpop(unsigned long *pc)
case OP_INDEXADDR: case OP_INDEXADDR:
printf(" %ld %ld\n", pc[0], pc[1]); printf(" %ld %ld\n", pc[0], pc[1]);
return 3; return 3;
case OP_PRINT: case OP_JUMPEQ: case OP_JUMPNE: case OP_JUMP: case OP_PRINT: case OP_JUMPZ: case OP_JUMPNZ: case OP_JUMP:
case OP_CONDORJUMP: case OP_CONDANDJUMP: case OP_CASEJUMP: case OP_CONDORJUMP: case OP_CONDANDJUMP: case OP_CASEJUMP:
case OP_INITSTATIC: case OP_MATCREATE: case OP_OBJCREATE: case OP_INITSTATIC: case OP_MATCREATE: case OP_OBJCREATE:
case OP_SHOW: case OP_ELEMINIT: case OP_ELEMADDR: case OP_SHOW: case OP_ELEMINIT: case OP_ELEMADDR:
case OP_ELEMVALUE: case OP_ELEMVALUE: case OP_JUMPNN:
printf(" %ld\n", *pc); printf(" %ld\n", *pc);
return 2; return 2;
case OP_NUMBER: case OP_IMAGINARY: case OP_NUMBER: case OP_IMAGINARY:

View File

@@ -38,8 +38,8 @@
#define OP_DUPLICATE 23L /* duplicate top value on stack */ #define OP_DUPLICATE 23L /* duplicate top value on stack */
#define OP_POP 24L /* pop top value from stack */ #define OP_POP 24L /* pop top value from stack */
#define OP_RETURN 25L /* return value of function */ #define OP_RETURN 25L /* return value of function */
#define OP_JUMPEQ 26L /* jump if top value is zero */ #define OP_JUMPZ 26L /* jump if top value is zero */
#define OP_JUMPNE 27L /* jump if top value is nonzero */ #define OP_JUMPNZ 27L /* jump if top value is nonzero */
#define OP_JUMP 28L /* jump unconditionally */ #define OP_JUMP 28L /* jump unconditionally */
#define OP_USERCALL 29L /* call a user-defined function */ #define OP_USERCALL 29L /* call a user-defined function */
#define OP_GETVALUE 30L /* convert address to value */ #define OP_GETVALUE 30L /* convert address to value */
@@ -143,7 +143,8 @@
#define OP_BACKSLASH 128L /* unary backslash */ #define OP_BACKSLASH 128L /* unary backslash */
#define OP_SETMINUS 129L /* binary backslash */ #define OP_SETMINUS 129L /* binary backslash */
#define OP_PLUS 130L /* unary + */ #define OP_PLUS 130L /* unary + */
#define MAX_OPCODE 130L /* highest legal opcode */ #define OP_JUMPNN 131L /* jump if top value is non-null */
#define MAX_OPCODE 131L /* highest legal opcode */
/* /*

View File

@@ -521,12 +521,12 @@ qilog2(NUMBER *q)
else if (n > 0) { else if (n > 0) {
zshift(q->den, n, &tmp2); zshift(q->den, n, &tmp2);
c = zrel(tmp1, tmp2); c = zrel(tmp1, tmp2);
zfree(tmp2);
} else { } else {
zshift(tmp1, -n, &tmp2); zshift(tmp1, -n, &tmp2);
c = zrel(tmp2, q->den); c = zrel(tmp2, q->den);
}
if (n)
zfree(tmp2); zfree(tmp2);
}
if (c < 0) if (c < 0)
n--; n--;
return n; return n;

1
qio.c
View File

@@ -558,6 +558,7 @@ str2q(char *s)
q->num = newnum; q->num = newnum;
q->den = newden; q->den = newden;
} }
zfree(div);
} }
return q; return q;
} }

14
qmath.c
View File

@@ -21,8 +21,6 @@ NUMBER _qnegone_ = { { _oneval_, 1, 1 }, { _oneval_, 1, 0 }, 1, NULL };
NUMBER _qonehalf_ = { { _oneval_, 1, 0 }, { _twoval_, 1, 0 }, 1, NULL }; NUMBER _qonehalf_ = { { _oneval_, 1, 0 }, { _twoval_, 1, 0 }, 1, NULL };
NUMBER _qonesqbase_ = { { _oneval_, 1, 0 }, { _sqbaseval_, 2, 0 }, 1, NULL }; NUMBER _qonesqbase_ = { { _oneval_, 1, 0 }, { _sqbaseval_, 2, 0 }, 1, NULL };
#define INITCONSTCOUNT 8
NUMBER * initnumbs[INITCONSTCOUNT] = {&_qzero_, &_qone_, &_qtwo_, &_qthree_, NUMBER * initnumbs[INITCONSTCOUNT] = {&_qzero_, &_qone_, &_qtwo_, &_qthree_,
&_qfour_, &_qten_, &_qnegone_, &_qonehalf_}; &_qfour_, &_qten_, &_qnegone_, &_qonehalf_};
@@ -1365,8 +1363,8 @@ qcmpi(NUMBER *q, long n)
#define NNALLOC 1000 #define NNALLOC 1000
static NUMBER *freeNum; static NUMBER *freeNum = NULL;
static NUMBER **firstNums; static NUMBER **firstNums = NULL;
static long blockcount = 0; static long blockcount = 0;
@@ -1389,8 +1387,12 @@ qalloc(void)
temp->links = 0; temp->links = 0;
} }
blockcount++; blockcount++;
newfn = (NUMBER **) if (firstNums == NULL) {
realloc(firstNums, blockcount * sizeof(NUMBER *)); newfn = (NUMBER **) malloc(blockcount * sizeof(NUMBER *));
} else {
newfn = (NUMBER **)
realloc(firstNums, blockcount * sizeof(NUMBER *));
}
if (newfn == NULL) { if (newfn == NULL) {
math_error("Cannot allocate new number block"); math_error("Cannot allocate new number block");
/*NOTREACHED*/ /*NOTREACHED*/

View File

@@ -13,6 +13,8 @@
#include "zmath.h" #include "zmath.h"
#define INITCONSTCOUNT 8 /* number of initnumbs[] pre-defined constants */
/* /*
* Rational arithmetic definitions. * Rational arithmetic definitions.
@@ -198,6 +200,12 @@ extern NUMBER *qlegtoleg(NUMBER *q, NUMBER *epsilon, BOOL wantneg);
extern NUMBER *qpi(NUMBER *epsilon); extern NUMBER *qpi(NUMBER *epsilon);
/*
* pseudo-seed generator
*/
extern NUMBER *pseudo_seed(void);
/* /*
* external swap functions * external swap functions
*/ */

View File

@@ -480,6 +480,7 @@ qatan(NUMBER *q, NUMBER *epsilon)
zsqrt(ztmp2, &ztmp1, 24L); zsqrt(ztmp2, &ztmp1, 24L);
zfree(ztmp2); zfree(ztmp2);
zadd(ztmp1, D, &ztmp2); zadd(ztmp1, D, &ztmp2);
zfree(ztmp1);
zshift(X, m, &ztmp1); zshift(X, m, &ztmp1);
zfree(X); zfree(X);
zquo(ztmp1, ztmp2, &X, 24L); zquo(ztmp1, ztmp2, &X, 24L);
@@ -726,6 +727,7 @@ qpi(NUMBER *epsilon)
zfree(tmp2); zfree(tmp2);
shift += 12; shift += 12;
} while ((shift - t) < bits); } while ((shift - t) < bits);
zfree(comb);
qtmp.num = _one_; qtmp.num = _one_;
qtmp.den = sum; qtmp.den = sum;
t1 = qscale(&qtmp, shift); t1 = qscale(&qtmp, shift);

Some files were not shown because too many files have changed in this diff Show More