Compare commits

...

16 Commits

Author SHA1 Message Date
Landon Curt Noll
2c9b160dc5 Release calc version 2.11.0t10.4 2017-05-21 15:38:35 -07:00
Landon Curt Noll
fbd3a79eba Release calc version 2.11.0t10.3.1 2017-05-21 15:38:35 -07:00
Landon Curt Noll
025b5e58d6 Release calc version 2.11.0t10.3 2017-05-21 15:38:35 -07:00
Landon Curt Noll
160f4102ab Release calc version 2.11.0t10.2 2017-05-21 15:38:34 -07:00
Landon Curt Noll
306e031f03 Release calc version 2.11.0t10.1.4 2017-05-21 15:38:34 -07:00
Landon Curt Noll
6cfe9696ce Release calc version 2.11.0t10.1.3 2017-05-21 15:38:34 -07:00
Landon Curt Noll
97ed812cb9 Release calc version 2.11.0t10.1.2 2017-05-21 15:38:34 -07:00
Landon Curt Noll
6254c4a14c Release calc version 2.11.0t10.1.1 2017-05-21 15:38:34 -07:00
Landon Curt Noll
c7c0de97f2 Release calc version 2.11.0t10.1 2017-05-21 15:38:34 -07:00
Landon Curt Noll
96c34adee3 Release calc version 2.11.0t10 2017-05-21 15:38:33 -07:00
Landon Curt Noll
86c8e6dcf1 Release calc version 2.11.0t9.4.5 2017-05-21 15:38:33 -07:00
Landon Curt Noll
58d32c68f9 Release calc version 2.11.0t9.4.4 2017-05-21 15:38:33 -07:00
Landon Curt Noll
7d0b761de3 Release calc version 2.11.0t9.4.3 2017-05-21 15:38:33 -07:00
Landon Curt Noll
82ff31f246 Release calc version 2.11.0t9.4.2 2017-05-21 15:38:32 -07:00
Landon Curt Noll
7cb0a77c25 Release calc version 2.11.0t9.4.1 2017-05-21 15:38:32 -07:00
Landon Curt Noll
afb0e5c32a Release calc version 2.11.0t9.4 2017-05-21 15:38:32 -07:00
311 changed files with 6372 additions and 4375 deletions

93
BUGS
View File

@@ -24,30 +24,26 @@ To be sure that your version of calc is up to date, check out:
The calc web site is located at:
http://reality.sgi.com/chongo/tech/comp/calc
http://reality.sgi.com/chongo/tech/comp/calc/index.html
=-=
If you have tried all of the above and things still are not right,
then it may be time to send in a bug report. You can send bug reports to:
calc-tester@postofc.corp.sgi.com
calc-bugs at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
When you send your report, please include the following information:
* a description of the problem
* the version of calc you are using (if you cannot get calc
it to run, then send us the 4 #define lines from version.c)
* if you modified calc from an official patch, send me the mods you made
* the type of system you were using
* the type of compiler you were using
* any compiler warnings or errors that you saw
* cd to the calc source directory, and type:
make debug > debug.out 2>&1 (sh, ksh, bash users)
@@ -62,7 +58,12 @@ Stack traces from core dumps are useful to send as well.
Send any comments, compiler warning messages, suggestions and most
importantly, fixes (in the form of a context diff patch) to:
calc-tester@postofc.corp.sgi.com
calc-tester at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
You should use the above calc-bugs address for bug reports, if you are
not currently a member of the calc-tester mailing list.
=-=
@@ -96,31 +97,54 @@ Known bugs:
the terminal in a 'bad' state, as if stty -icanon -echo -echoe
had been executed.
* Dec Alpha Linux compiling with gcc-2.95.1 (or gcc-2.95.2) and
-O2 fails the version 2.11.0t8.10 regression test with:
* Use of 'fmt' in the 2nd arg of printf() calls in c_sysinfo.c
cause some compilers to issue warnings.
make -s check
000: Beginning regression tests
001: Some of these tests may take a while ...
002: Within each section, output should be numbered sequentially
003: parsed global definitions
004: parsed vrfy()
005: parsed prob(str)
006: parsed getglobalvar()
007: parsed test_booleans()
008: parsed test_variables()
make: *** [check] Segmentation fault (core dumped)
We are sure some more bugs exist. When you find them, please let
us know! See the above for details on how to report and were to
EMail your bug reports and hopefully patches to fix them.
Other programs have reported problems when compiling -O2 with
gcc-2.95.1 on the Alpha and Mips.
=-=
One work-a-round is to not compile with -O2 (perhaps just -O).
Another work-a-round is not use gcc-2.95.1.
Problems with known work-a-rounds:
* There is a bug in gcc-2.95 that causes calc, when compiled with -O2,
to fail the regression test. The work-a-round is to compile with -O
or to use gcc-2.96 or later.
* Solaris cc somtimes barfs while compiling zrand.c. In particular, calc
barfs on on the SVAL macro. The work-a-round is to use the Solaric cc
Makefile set sets -DFORCE_STDC. I.e,:
CCWARN=
CCOPT= ${DEBUG} ${NO_SHARED}
CCMISC= -DFORCE_STDC
#
CFLAGS= ${CCWARN} ${CCOPT} ${CCMISC}
ICFLAGS= ${CCWARN} ${CCMISC}
#
LCFLAGS=
LDFLAGS= ${NO_SHARED} ${LD_NO_SHARED}
ILDFLAGS=
#
LCC= cc
CC= ${PURIFY} ${LCC}
* There is a bug in some versions of the Dec/Compaq cc for the Alpha
where the following:
#include <stdio.h>
#define SVAL(a,b) (unsigned long)(0x ## a ## b ## ULL)
main(){SVAL(b8a8aeb0,8168eadc);}
fails because it puts a space inside the concatenated hex. Calc
has code that is affected by this bug. This bug has been reported
to Compaq and may be fixed in the future. A work-a-round is to
compile with cc -std0 or to use a later version of their compiler.
* On a Digital UNIX V4.0F (Rev. 1229) on a 500 Mhz 21264, make check
dies a horrible death starting in test 600 and 622 gives 100s of
messages for calc version 2.11.0t9.2 using the Dec's cc with -O2
and without -std0:
messages for calc version 2.11.0t9.4 using the Dec's cc with -O2:
600: Beginning test_bignums
601: muldivcheck 1
@@ -135,6 +159,13 @@ Known bugs:
it finally hangs at test 2000.
We are sure some more bugs exist. When you find them, please let
us know! See the above for details on how to report and were to
EMail your bug reports and hopefully patches to fix them.
The work-a-round is to compile calc without the optimizer. If this
happens to you, try compiling without -O and without -O2. I.e., in
the Makefile, set:
DEBUG= -g
* The sparcv9 support for 64 bit Solaris under gcc-2.96 is able
to compile calc, but calc dumps core very early on in startup.
It is said that sparcv9 support in gcc-2.96 is very unofficial.
There is no work-a-round for this compiler problem.

301
CHANGES
View File

@@ -1,4 +1,112 @@
Following is the change from calc version 2.11.0t8.9.1 to date:
The following are the changes from calc version 2.11.0t10 to date:
Misc code cleanup. Removed dead code. Removed trailing whitespace.
Fixed whitespace to make the best use of 8 character tabs.
Fixed some bugs relaing to '// and %' in combination with some
of the the rounding modes based on a patch from Ernest Bowen
<ernie@turing.une.edu.au>.
A patch from Klaus Alexander Seistrup <klaus@seistrup.dk>, when
used in combination with the GNU-readline facility, will prevent
it from saving empty lines.
Minor typos fixed in regress.cal
Added 8500 test serise and test8500.cal to perform more extensive
tests on // and % with various rounding modes.
The 'unused value ignored' messages now start with Line 999: instead
of just 999:.
Fixed the long standing issue first reported by Saber-C in the
domul() function in zmil.c thanks to a patch by Ernest Bowen
<ernie@turing.une.edu.au>.
Added zero dimensional matrices. A zero dimensional matrix is defined as:
mat A[] or A = mat[]
Updated the help/mat file to reflect the current status of matrices
including zero dimensional matrices.
Added indices() builtin function as written by Ernest Bowen
<ernie@turing.une.edu.au> developed from an idea of Klaus Seistrup
<klaus@seistrup.dk>. See help/indices for details.
Fixed a number of insure warnings as reported by Michel van der List
<vanderlistmj@sbphrd.com>.
Fixed a number of help file typos discovered by Klaus Alexander
Seistrup <klaus@seistrup.dk>.
Removed REGRESS_CAL as a Makefile variable.
Added calcliblist and calcliblistfmt utility Makefile rules to allow
one to print the list of distribution files that are used (but not
built) to form either the libcalc.a or the libcustcalc.a library.
Added a patch from Randall.Gray@marine.csiro.au to make ^D terminate,
but *only* if the line it is on is completely empty. Removed lib/altbind
and removed the CALCBINDINGS Makefile variable.
A new config("ctrl_d") value controls how the ``delete_char'', which
by default is bound to ^D (Control D), will or will not exit calc:
config("ctrl_d", "virgin_eof")
If ^D is the only character that has been typed on a line,
then calc will exit. Otherwise ^D will act according to the
calc binding, which by default is a Emacs-style delete-char.
This is the default mode.
config("ctrl_d", "never_eof")
The ^D never exits calc and only acts according calc binding,
which by default is a Emacs-style delete-char.
Emacs purists may want to set this in their ~/.calcrc startup file.
config("ctrl_d", "empty_eof")
The ^D always exits calc if typed on an empty line. This
condition occurs when ^D either the first character typed,
or when all other characters on the line have been removed
(say by deleting them).
Users who always want to exit when ^D is typed at the beginning
of a line may want to set this in their ~/.calcrc startup file.
Note that config("ctrl_d") apples to the character bound to each
and every ``delete_char''. So if an alternate binding it setup,
then those char(s) will have this functionality.
Updated help/config and help/mode, improved the readability and
fixed a few typos. Documented modes, block formats and block bases
("mode", "blkfmt" & "blkbase") that were previously left off out of
the documentation.
The config("blkbase") and config("blkfmt") values return strings
instead of returning integers. One cannot use integers to set
these values, so returning integers was useless.
The following config values return "on" or "off" strings:
tilde tab leadzero fullzero blkverbose verbose_quit
These config values can still be set with same boolean strings
("on", "off", "true", "false", "t", ...) as well as via the
numerical values 0 (for "off") and non-0 (for "on"), however.
Applied the dangling name fix from Ernest Bowen <ernie@turing.une.edu.au>.
Show func prints function on order of their indices, and with
config("lib_debug") & 4 == 4 some more details about the functions
are displayed.
The following are the changes from calc version 2.11.0t8.9.1 to 2.11.0t9.4.5:
The config("verbose_quit") will control the printing of the message:
@@ -108,16 +216,135 @@ Following is the change from calc version 2.11.0t8.9.1 to date:
in addition to pre-installing GNU-readline in your system to use
this facility.
Changed the "object already defined" math_error message to a
scanerror message.
Changed the "object already defined" math_error to a scanerror message.
Removed the limit on the number of object types.
Calc tarballs are now named calc-version.tar.gz and untar into
a sub-directory called calc-version.
Made a small change to declarations of static variables to reduce
the internal opcodes needed to declare them.
Following is the change from calc version 2.11.0t8 to 2.11.0t8.9:
Fixed a permission problem on ranlib-ed *.a files that was reported
by Michael Somos <somos@grail.cba.csuohio.edu>.
Added patch by Klaus Alexander Seistrup <klaus@seistrup.dk> related
to GNU-readline:
+ enable calc specific bindings in ~/.inputrc
+ save a copy of your session to disk and reload them next
time you're using calc
+ only add a line to the history if it is different from
the previous line
Added the Makefile symbol HAVE_GETRUSAGE to determine if the
system supports the getrusage() system call.
Fixed the make depend code in the custom and sample Makefiles.
Fixed how the help/builtin file is formed. The help/Makefile is
now given the name of the native C compiler by the top level Makefile.
The include files are installed under INCDIRCALC (a new Makefile variable)
which by default is ${INCDIR}/calc. The INCDIR (also a new Makefile var)
by default is /usr/local/include. Include files previously installed
directly under ${LIBDIR} will be removed.
Added the piforever() funcion to lib/pi.cal. It was written by
Klaus Alexander Seistrup <klaus@seistrup.dk> and was inspired by
an algorithm conceived by Lambert Meertens. (See also the ABC
Programmer's Handbook, by Geurts, Meertens & Pemberton, published
by Prentice-Hall (UK) Ltd., 1990.) The piforever() funcion prints
digits of pi for as long as your memory and system uptime allows. :-)
Fixed the URLs found thruout the source and documentation which did
not and in /, but should for performance and server load reasons.
Cleaned up and improved handling of "mat" and "obj". The comma in:
mat A[2], B[3];
is changed to whatever is appropriate in the context:
+ comma operator
+ separator of arguments in a function call
+ separator of arguments in a defintion
etc.
The expression (mat A[2]), B[3] returns B[3], assuming B already
exists as something created by a statement like: global mat B[4].
What used to be done by the expression:
mat A[2], B[3]
will now require something like:
mat A[2], mat B[3] or A = mat[2], B = mat[3]
For example, if obj point and obj pair are known types, the
following is now allowed:
L = list(mat[2], mat[3], obj point, obj pair)
As another example, the following is allowed:
define f(a = mat[2] = {3,4}) = 5 * a;
as well as the following:
obj point {x,y}, PP = obj pair {A,B} = {obj point, obj point}
which creates two object types at compile time and when executed,
assigns a pair-object value to a variable PP.
Fixed a bug whereby a for loop would behave incorrectly. For example:
config("trace", 2),
global x;
define f() {for ( ; x > 0; x--) {print x;}}
x = 5, f()
will stop after printing 1 instead of looping forever.
Added values l_format, which when CHECK_L_FORMAT is defined ahead
of including longlong.h will help detect when a system can deal with
'long long' but not '%lld' in printf. If a system with 'long long'
uses '%ld' to print a 64 bit value, then l_format will be > 0;
othewise if "%lld" is required, l_format will be < 0.
Added HAVE_STRDUP Makefile variable as well as the have_strdup.c
program that forms the have_strdup.h file. The have_strdup.h file
will define HAVE_STRDUP is the system has strdup(). If HAVE_STRDUP
is not defined, then calc will use calc_strdup() to simulate
the real strdup() function.
Calc no longer makes use of sys_errlist and sys_nerr. Some systems
no longer suppor these values (even though they should from a
legacy prospective). Calc now relies on the fact that strerror()
will return NULL of no such system error exists. System errors >=
10000 will be considered calc errors instead. The Makefile symbol
ERRNO_DECL has gone away as well as calc_errno.c and calc_errno.h.
System errors that are are not known to to the libc strerror()
function, will now print (via the strerror() calc builtin function)
something such as:
Unknown error 9999
Fixed some insure code inspection tool issues that were discovered
and investigated by Michel van der List <vanderlistmj@sbphrd.com>.
Made an effort to ensure that the v_subtype of VALUES are initialized
to V_NOSUBTYPE thruout the source code.
Established a separate calc-bugs address from the calc-tester
maining list. Using anti-spam address forms in order to try and
stay under the radar of spammers as much as one can do so.
The following are the changes from calc version 2.11.0t8 to 2.11.0t8.9:
Moved 'wishlist' enhancements from the help/todo file to a new
help/wishlist file. Ordered, by priority, help/todo items into
@@ -273,7 +500,7 @@ Following is the change from calc version 2.11.0t8 to 2.11.0t8.9:
Fixed misc compiler warnings.
Following is the change from calc version 2.11.0t7 to 2.11.0t7.5:
The following are the changes from calc version 2.11.0t7 to 2.11.0t7.5:
Calc has some new command line flags / command line meaning:
(Thanks goes to Ernest Bowen <ernie@turing.une.edu.au>)
@@ -416,12 +643,12 @@ Following is the change from calc version 2.11.0t7 to 2.11.0t7.5:
The main calc URL is now:
http://reality.sgi.com/chongo/tech/comp/calc
http://reality.sgi.com/chongo/tech/comp/calc/
Misc calc man page fixes.
Following is the change from calc version 2.11.0t1 to 2.11.0t6.3:
The following are the changes 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;
@@ -613,12 +840,12 @@ Following is the change from calc version 2.11.0t1 to 2.11.0t6.3:
Fixed misc compile warnings and notices.
Following is the change from calc version 2.10.3t5.38 to 2.11.0t0:
The following are the changes from calc version 2.10.3t5.38 to 2.11.0t0:
Fixed a few compile problems found under Red Hat 6.0 Linux.
Following is the change from calc version 2.10.3t5.38 to 2.11.3t5.46:
The following are the changes from calc version 2.10.3t5.38 to 2.11.3t5.46:
Fixed a bug discovered by Ernest Bowen related to matrix-to-matrix copies.
@@ -675,7 +902,7 @@ Following is the change from calc version 2.10.3t5.38 to 2.11.3t5.46:
into a single section.
Following is the change from calc version 2.10.3t5.34 to 2.10.3t5.37:
The following are the changes from calc version 2.10.3t5.34 to 2.10.3t5.37:
Per request from David I Bell, the README line:
@@ -1194,7 +1421,7 @@ Following is the change from calc version 2.10.3t5.34 to 2.10.3t5.37:
user-specified bound.
Following is the change from calc version 2.10.3t5.28 to 2.10.3t5.33:
The following are the changes from calc version 2.10.3t5.28 to 2.10.3t5.33:
Added hnrmod(v, h, n, r) builtin to compute:
@@ -1556,11 +1783,11 @@ Following is the change from calc version 2.10.3t5.28 to 2.10.3t5.33:
Added regression tests related to saveval(), dot and pointers.
Following is the change from calc version 2.10.3t5.11 to 2.10.3t5.27:
The following are the changes from calc version 2.10.3t5.11 to 2.10.3t5.27:
The todo help file as been updated with the in-progress items:
XXX - block print function is not written yet ...
xxx - block print function is not written yet ...
Expanded the role of blk() to produce unnamed blocks as in:
@@ -1698,7 +1925,7 @@ Following is the change from calc version 2.10.3t5.11 to 2.10.3t5.27:
where x was not 2^n-1 would leak memory. This has been fixed.
Following is the change from calc version 2.10.3t5.1 to 2.10.3t5.10:
The following are the changes from calc version 2.10.3t5.1 to 2.10.3t5.10:
Misc printf warning bug fixes.
@@ -1899,7 +2126,7 @@ Following is the change from calc version 2.10.3t5.1 to 2.10.3t5.10:
regression tests for memsize(), sizeof() and size().
Following is the change from calc version 2.10.3t4.16 to 2.10.3t5.0:
The following are the changes from calc version 2.10.3t4.16 to 2.10.3t5.0:
The calc source now comes with a custom sub-directory which
contains the custom interface code. The main Makefile now
@@ -2091,7 +2318,7 @@ Following is the change from calc version 2.10.3t4.16 to 2.10.3t5.0:
The max(), min() builtins work for lists.
Following is the change from calc version 2.10.3t3 to 2.10.3t4.15:
The following are the changes from calc version 2.10.3t3 to 2.10.3t4.15:
The priority of unary + and - to that of binary + and - when they are
applied to a first or only term. Thus:
@@ -2267,7 +2494,7 @@ Following is the change from calc version 2.10.3t3 to 2.10.3t4.15:
Fixed error in using cmdbuf("").
Following is the change from calc version 2.10.3t0 to 2.10.3t2:
The following are the changes from calc version 2.10.3t0 to 2.10.3t2:
Bumped to version 2.10.3 due to the amount of changes.
@@ -2429,7 +2656,7 @@ Following is the change from calc version 2.10.3t0 to 2.10.3t2:
SGI 6.2 and later uses -xansi.
Following is the change from calc version 2.10.2t33 to 2.10.2t34:
The following are the changes from calc version 2.10.2t33 to 2.10.2t34:
Fixed a bug related to fact().
@@ -2506,7 +2733,7 @@ Following is the change from calc version 2.10.2t33 to 2.10.2t34:
http://www.latech.edu/~acm/HelloWorld.shtml
Following is the change from calc version 2.10.2t25 to 2.10.2t32:
The following are the changes from calc version 2.10.2t25 to 2.10.2t32:
Eliminated use of VARARG and <varargs.h>. Calc supports only
<stdarg.h>. The VARARGS Makefile variable has been eliminated.
@@ -2690,7 +2917,7 @@ Following is the change from calc version 2.10.2t25 to 2.10.2t32:
and file system permits.
Following is the change from calc version 2.10.2t4 to 2.10.2t24:
The following are the changes from calc version 2.10.2t4 to 2.10.2t24:
Added makefile debugging rules:
@@ -2975,7 +3202,7 @@ Following is the change from calc version 2.10.2t4 to 2.10.2t24:
SWAP_HALF_IN_OFF_T.
Following is the change from calc version 2.10.2t1 to 2.10.2t3:
The following are the changes from calc version 2.10.2t1 to 2.10.2t3:
Fixed bug in the regression suite that made test3400 and test4100
fail on correct computations.
@@ -3151,7 +3378,7 @@ Following is the change from calc version 2.10.2t1 to 2.10.2t3:
treated as read-only.
Following is the change from calc version 2.10.1t21 to 2.10.2t0:
The following are the changes from calc version 2.10.1t21 to 2.10.2t0:
Bumped patch level 2.10.2t0 in honor of having help files for
all builtin functions. Beta release will happen at the end of
@@ -3233,7 +3460,7 @@ Following is the change from calc version 2.10.1t21 to 2.10.2t0:
mat D[] = { }
Following is the change from calc version 2.10.1t20 to 2.10.1t20:
The following are the changes from calc version 2.10.1t20 to 2.10.1t20:
Changes made in preparation for Blum Blum Shub random number generator.
@@ -3310,7 +3537,7 @@ Following is the change from calc version 2.10.1t20 to 2.10.1t20:
<ernie@neumann.une.edu.au>
Following is the change from calc version 2.10.1t11 to 2.10.1t19:
The following are the changes from calc version 2.10.1t11 to 2.10.1t19:
Added many more regression tests to lib/regress.cal. Some
due to <ernie@neumann.une.edu.au>.
@@ -3510,7 +3737,7 @@ Following is the change from calc version 2.10.1t11 to 2.10.1t19:
Ha Lam <hl@kuhep5.phsx.ukans.edu>
Following is the change from calc version 2.10.0t13 to 2.10.1t10:
The following are the changes from calc version 2.10.0t13 to 2.10.1t10:
Added SB8, USB8, SB16, USB16, SB32, USB32 typedefs, determined by
longbits and declared in longbits.h, to deal with 8, 16 and 32 bit
@@ -3627,7 +3854,8 @@ Following is the change from calc version 2.10.0t13 to 2.10.1t10:
digits or bits rather than places, e.g. round(.00238, 2, 32)
returns .0023, round(.00238, 2, 56) returns .0024.
Following is the change from calc version 2.9.3t11 to 2.10.0t12:
The following are the changes from calc version 2.9.3t11 to 2.10.0t12:
The default ${LIBDIR}/bindings CALCBINDINGS uses ^D for editing.
The alternate CALCBINDINGS ${LIBDIR}/altbind uses ^D for EOF.
@@ -3681,7 +3909,8 @@ Following is the change from calc version 2.9.3t11 to 2.10.0t12:
to provide a more extensive test suite for some builtin numeric
functions.
Following is the change from calc version 2.9.3t9.2+ to 2.9.3t10:
The following are the changes from calc version 2.9.3t9.2+ to 2.9.3t10:
Added many help files for builtin functions and some symbols.
More help files are needed, see help/todo.
@@ -3784,7 +4013,8 @@ Following is the change from calc version 2.9.3t9.2+ to 2.9.3t10:
{
}
Following is the change from calc version 2.9.3t8 to 2.9.3t9.2:
The following are the changes from calc version 2.9.3t8 to 2.9.3t9.2:
Use of the macro zisleone(z) has been clarified. The zisleone(z) macro
tests if z <= 1. The macro zisabsleone(z) tests of z is 1, 0 or -1.
@@ -3992,7 +4222,8 @@ Following is the change from calc version 2.9.3t8 to 2.9.3t9.2:
Fixed bug where reserved keyword used as symbol name caused a core dump.
Following is the change from calc version 2.9.3t7 to 2.9.3t7:
The following are the changes from calc version 2.9.3t7 to 2.9.3t7:
The 'show' command by itself will issue an error message
that will remind one of the possible show arguments.
@@ -4039,7 +4270,8 @@ Following is the change from calc version 2.9.3t7 to 2.9.3t7:
Added utoz(), ztou() to zmath.c, and utoq(), qtou() to qmath.c
in preparation for 2.9.3t9 mods.
Following is the change from calc version 2.9.2 to 2.9.3t7:
The following are the changes from calc version 2.9.2 to 2.9.3t7:
Calc can now compile on OSF/1, SGI and IBM RS6000 systems.
@@ -4160,7 +4392,8 @@ Following is the change from calc version 2.9.2 to 2.9.3t7:
Updated the help/todo list. A BUGS file was added. Volunteers are
welcome to send in patches!
Following is the change from calc version 2.9.1 to 2.9.1:
The following are the changes from calc version 2.9.1 to 2.9.1:
Fixed floor() for values -1 < x < 0.
@@ -4174,12 +4407,14 @@ Following is the change from calc version 2.9.1 to 2.9.1:
Added more regression test code.
Following is the change from calc version 2.9.0 to 2.9.0:
The following are the changes from calc version 2.9.0 to 2.9.0:
A major bug was fixed in subtracting two numbers when the first
number was zero. The problem caused wrong answers and core dumps.
Following is a list of visible changes to calc from version 1.27.0 to 2.8.0:
The following are the changes from calc version 1.27.0 to 2.8.0:
Full prototypes have been provided for all C functions, and are used
if calc is compiled with an ANSI compiler.

View File

@@ -19,11 +19,6 @@ Installing calc in 4 easy steps:
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.

479
Makefile
View File

@@ -261,6 +261,30 @@ HAVE_GETPRID=
HAVE_URANDOM=
#HAVE_URANDOM= -DHAVE_NO_URANDOM
# Determine if we have getrusage()
#
# If HAVE_GETRUSAGE is empty, this makefile will run the have_memmv program
# to determine if getrusage() is supported. If HAVE_GETRUSAGE is set to
# -DHAVE_NO_GETRUSAGE, then calc will use internal functions to simulate
# the memory move function that does correct overlapping memory modes.
#
# If in doubt, leave HAVE_GETRUSAGE empty and this Makefile will figure it out.
#
HAVE_GETRUSAGE=
#HAVE_GETRUSAGE= -DHAVE_NO_GETRUSAGE
# Determine if we have strdup()
#
# If HAVE_STRDUP is empty, this makefile will run the have_memmv program
# to determine if strdup() is supported. If HAVE_STRDUP is set to
# -DHAVE_NO_STRDUP, then calc will use internal functions to simulate
# the memory move function that does correct overlapping memory modes.
#
# If in doubt, leave HAVE_STRDUP empty and this Makefile will figure it out.
#
HAVE_STRDUP=
#HAVE_STRDUP= -DHAVE_NO_STRDUP
# Some architectures such as Sparc do not allow one to access 32 bit values
# that are not alligned on a 32 bit boundary.
#
@@ -278,39 +302,6 @@ HAVE_URANDOM=
ALIGN32= -DMUST_ALIGN32
#ALIGN32= -UMUST_ALIGN32
# On most machines: errno sys_errlist and sys_nerr are declared
# by either <stdio.h> and/or <errno.h>. But some systems declare
# them somewhere else or do not declare them at all!
#
# If the system were doing a proper job in headers, this should declare them:
#
# #include <stdio.h>
# #include <errno.h>
#
# But one some systems one must explicitly declare them as:
#
# extern int errno;
# extern const char *const sys_errlist[];
# extern int sys_nerr;
#
# and on some old systems they must be explicitly and incorrectly declared as:
#
# extern int errno;
# extern char *sys_errlist[];
# extern int sys_nerr;
#
# ERRNO_DECL= let calc_errno.c determine how to declare them
# ERRNO_DECL= -DERRNO_NO_DECL headers declare them correctly
# ERRNO_DECL= -DERRNO_STD_DECL one must explicitly declare then
# ERRNO_DECL= -DERRNO_OLD_DECL one must explicitly & incorrectly declare them
#
# When in doubt, be safe leave ERRNO_DECL empty.
#
ERRNO_DECL=
#ERRNO_DECL= -DERRNO_NO_DECL
#ERRNO_DECL= -DERRNO_STD_DECL
#ERRNO_DECL= -DERRNO_OLD_DECL
# where to install binary files
#
BINDIR= /usr/local/bin
@@ -320,7 +311,9 @@ BINDIR= /usr/local/bin
# where to install the *.cal, *.h and *.a files
#
# ${TOPDIR} is the directory under which the calc directory will be placed.
# ${LIBDIR} is where the *.cal, *.h, *.a, bindings and help dir are installed.
# ${LIBDIR} is where the *.cal, *.a, bindings and help dir are installed.
# ${INCDIR} is where the locally installed include files are found.
# ${INCDIRCALC} is where the calc include files are installed.
# ${HELPDIR} is where the help directory is installed.
# ${CUSTOMLIBDIR} is where custom lib files are installed.
# ${CUSTOMHELPDIR} is where custom help files are installed.
@@ -332,6 +325,8 @@ TOPDIR= /usr/local/lib
#
LIBDIR= ${TOPDIR}/calc
HELPDIR= ${LIBDIR}/help
INCDIR= /usr/local/include
INCDIRCALC= ${INCDIR}/calc
CUSTOMLIBDIR= ${LIBDIR}/custom
CUSTOMHELPDIR= ${HELPDIR}/custhelp
@@ -407,23 +402,11 @@ CALCPATH= .:./lib:~/lib:${LIBDIR}:${CUSTOMLIBDIR}
#
CALCRC= ${LIBDIR}/startup:~/.calcrc
# If the $CALCBINDINGS environment variable is not defined, then the following
# file will be used for the command line and edit history key bindings.
# The $CALCPATH will be used to search for this file.
#
# ${LIBDIR}/bindings uses ^D for editing
# ${LIBDIR}/altbind uses ^D for EOF
#
# NOTE: This facility is disabled if USE_READLINE is set to -DUSE_READLINE.
#
CALCBINDINGS= bindings
#CALCBINDINGS= altbind
# Determine of the GNU-readline facility will be used instead of the
# built-in CALCBINDINGS above.
# built-in calc binding method.
#
# USE_READLINE= Do not use GNU-readline, use CALCBINDINGS
# USE_READLINE= -DUSE_READLINE Use GNU-readline, do not use CALCBINDINGS
# USE_READLINE= Do not use GNU-readline, use calc bindings
# USE_READLINE= -DUSE_READLINE Use GNU-readline, do not use calc bindings
#
# NOTE: If you select the 'USE_READLINE= -DUSE_READLINE' mode, you must set:
#
@@ -438,12 +421,16 @@ CALCBINDINGS= bindings
# If in doubt, set USE_READLINE, READLINE_LIB and READLINE_INCLUDE to nothing.
#
USE_READLINE=
READLINE_LIB=
READLINE_INCLUDE=
#
#USE_READLINE= -DUSE_READLINE
#
READLINE_LIB=
#READLINE_LIB= -L/usr/gnu/lib -lreadline -lhistory
#READLINE_LIB= -lreadline -lhistory
#READLINE_INCLUDE= -I/usr/include/readline
#READLINE_LIB= -L/usr/local/lib -lreadline -lhistory
#
READLINE_INCLUDE=
#READLINE_INCLUDE= -I/usr/gnu/include
#READLINE_INCLUDE= -I/usr/local/include
# If $PAGER is not set, use this program to display a help file
#
@@ -742,7 +729,7 @@ CC= ${PURIFY} ${LCC}
#
###
#
# RS6000 set
# AIX RS/6000 set
#
#CCWARN=
#CCOPT= ${DEBUG} ${NO_SHARED}
@@ -838,6 +825,7 @@ SORT= sort
TEE= tee
LINT= lint
CTAGS= ctags
FMT= fmt
# assume the X11 makedepend tool for the depend rule
MAKEDEPEND= makedepend
# echo command location
@@ -909,9 +897,10 @@ BUILD_H_SRC= align32.h args.h calcerr.h conf.h endian_calc.h \
fposval.h have_const.h have_fpos.h have_malloc.h \
have_memmv.h have_newstr.h have_offscl.h have_posscl.h \
have_stdlib.h have_string.h have_times.h have_uid_t.h \
have_unistd.h longbits.h longlong.h terminal.h calc_errno.h \
have_unistd.h longbits.h longlong.h terminal.h \
have_ustat.h have_getsid.h have_getpgid.h \
have_gettime.h have_getprid.h have_urandom.h
have_gettime.h have_getprid.h have_urandom.h have_rusage.h \
have_strdup.h
# we build these .c files during the make
#
@@ -923,9 +912,9 @@ BUILD_C_SRC= calcerr.c
#
UTIL_C_SRC= align32.c endian.c longbits.c have_newstr.c have_uid_t.c \
have_const.c have_stdvs.c have_varvs.c fposval.c have_fpos.c \
longlong.c have_offscl.c have_posscl.c have_memmv.c calc_errno.c \
longlong.c have_offscl.c have_posscl.c have_memmv.c \
have_ustat.c have_getsid.c have_getpgid.c \
have_gettime.c have_getprid.c
have_gettime.c have_getprid.c have_rusage.c have_strdup.c
# these awk and sed tools are used in the process of building BUILD_H_SRC
# and BUILD_C_SRC
@@ -939,31 +928,22 @@ UTIL_MISC_SRC= calcerr_h.sed calcerr_h.awk calcerr_c.sed calcerr_c.awk \
#
UTIL_OBJS= endian.o longbits.o have_newstr.o have_uid_t.o \
have_const.o fposval.o have_fpos.o longlong.o try_strarg.o \
have_stdvs.o have_varvs.o have_posscl.o have_memmv.o calc_errno.o \
have_stdvs.o have_varvs.o have_posscl.o have_memmv.o \
have_ustat.o have_getsid.o have_getpgid.o \
have_gettime.o have_getprid.o ver_calc.o
have_gettime.o have_getprid.o ver_calc.o have_rusage.o have_strdup.o
# these temp files may be created (and removed) during the build of BUILD_C_SRC
#
UTIL_TMP= ll_tmp fpos_tmp fposv_tmp const_tmp uid_tmp newstr_tmp vs_tmp \
calc_errno_tmp memmv_tmp offscl_tmp posscl_tmp newstr_tmp \
getsid_tmp gettime_tmp getprid_tmp
memmv_tmp offscl_tmp posscl_tmp newstr_tmp \
getsid_tmp gettime_tmp getprid_tmp rusage_tmp strdup_tmp
# these utility progs may be used in the process of building BUILD_H_SRC
#
UTIL_PROGS= align32 fposval have_uid_t longlong have_const \
endian longbits have_newstr have_stdvs have_varvs calc_errno \
endian longbits have_newstr have_stdvs have_varvs \
have_ustat have_getsid have_getpgid \
have_gettime have_getprid ver_calc
# These files are required by the regress.cal regression test.
#
REGRESS_CAL= ./lib/lucas_chk.cal ./lib/natnumset.cal ./lib/surd.cal \
./lib/test1700.cal ./lib/test2300.cal ./lib/test2600.cal \
./lib/test2700.cal ./lib/test3100.cal ./lib/test3300.cal \
./lib/test3400.cal ./lib/test3500.cal ./lib/test4000.cal \
./lib/test4100.cal ./lib/test4600.cal ./lib/test5100.cal \
./lib/test5200.cal
have_gettime have_getprid ver_calc have_strdup
# The complete list of makefile vars passed down to custom/Makefile.
#
@@ -1020,6 +1000,31 @@ SAMPLE_PASSDOWN= Q="${Q}" \
MAKEDEPEND=${MAKEDEPEND} \
SORT=${SORT}
# The compelte list of makefile vars passed down to help/Makefile.
#
HELP_PASSDOWN= Q="${Q}" \
TOPDIR="${TOPDIR}" \
LIBDIR="${LIBDIR}" \
HELPDIR="${HELPDIR}" \
CFLAGS="${CFLAGS} ${ALLOW_CUSTOM}" \
ICFLAGS="${ICFLAGS}" \
ILDFLAGS="${ILDFLAGS}" \
LCC="${LCC}" \
MAKE_FILE=${MAKE_FILE} \
SED=${SED} \
FMT=${FMT}
# The compelte list of makefile vars passed down to lib/Makefile.
#
LIB_PASSDOWN= Q="${Q}" \
TOPDIR="${TOPDIR}" \
LIBDIR="${LIBDIR}" \
HELPDIR="${HELPDIR}" \
MAKE_FILE=${MAKE_FILE} \
SED=${SED} \
MAKEDEPEND=${MAKEDEPEND} \
SORT=${SORT}
# complete list of .h files found (but not built) in the distribution
#
H_SRC= ${LIB_H_SRC}
@@ -1033,6 +1038,11 @@ C_SRC= ${LIBSRC} ${CALCSRC} ${UTIL_C_SRC}
DISTLIST= ${C_SRC} ${H_SRC} ${MAKE_FILE} BUGS CHANGES LIBRARY README \
calc.man lint.sed HOWTO.INSTALL ${UTIL_MISC_SRC}
# These files are used to make (but not built) a calc .a library
#
CALCLIBLIST= ${LIBSRC} ${UTIL_C_SRC} ${LIB_H_SRC} ${MAKE_FILE} \
${UTIL_MISC_SRC} BUGS CHANGES LIBRARY
# complete list of .o files
#
OBJS= ${LIBOBJS} ${CALCOBJS} ${UTIL_OBJS}
@@ -1066,13 +1076,13 @@ libcalc.a: ${LIBOBJS} ${MAKE_FILE}
-rm -f libcalc.a
ar qc libcalc.a ${LIBOBJS}
${RANLIB} libcalc.a
chmod 0644 libcalc.a
calc.1: calc.man ${MAKE_FILE}
-rm -f calc.1
${SED} -e 's:$${LIBDIR}:${LIBDIR}:g' \
-e 's,$${CALCPATH},${CALCPATH},g' \
-e 's,$${CALCRC},${CALCRC},g' \
-e 's,$${CALCBINDINGS},${CALCBINDINGS},g' < calc.man > calc.1
-e 's,$${CALCRC},${CALCRC},g' < calc.man > calc.1
##
#
@@ -1081,7 +1091,7 @@ calc.1: calc.man ${MAKE_FILE}
##
calc.o: calc.c ${MAKE_FILE}
${CC} ${CFLAGS} ${CCOPT} ${ALLOW_CUSTOM} -c calc.c
${CC} ${CFLAGS} ${ALLOW_CUSTOM} -c calc.c
custom.o: custom.c ${MAKE_FILE}
${CC} ${CFLAGS} ${ALLOW_CUSTOM} -c custom.c
@@ -1136,11 +1146,6 @@ conf.h: ${MAKE_FILE}
${Q}echo '#define DEFAULTCALCRC "${CALCRC}"' >> conf.h
${Q}echo '#endif /* DEFAULTCALCRC */' >> conf.h
${Q}echo '' >> conf.h
${Q}echo '/* the default key bindings file */' >> conf.h
${Q}echo '#ifndef DEFAULTCALCBINDINGS' >> conf.h
${Q}echo '#define DEFAULTCALCBINDINGS "${CALCBINDINGS}"' >> conf.h
${Q}echo '#endif /* DEFAULTCALCBINDINGS */' >> conf.h
${Q}echo '' >> conf.h
${Q}echo '/* the location of the help directory */' >> conf.h
${Q}echo '#ifndef HELPDIR' >> conf.h
${Q}echo '#define HELPDIR "${HELPDIR}"' >> conf.h
@@ -1488,6 +1493,8 @@ longlong.h: longlong.c have_stdlib.h have_string.h ${MAKE_FILE}
else \
echo '#undef HAVE_LONGLONG' >> longlong.h; \
echo '#define LONGLONG_BITS 0 /* no */' >> longlong.h; \
echo '#undef LL_FORMAT' >> longlong.h; \
echo '#undef L_FORMAT' >> longlong.h; \
fi
${Q}echo '' >> longlong.h
${Q}echo '' >> longlong.h
@@ -2088,6 +2095,84 @@ have_urandom.h: ${MAKE_FILE}
true; \
fi
have_rusage.h: have_rusage.c ${MAKE_FILE}
-${Q}rm -f have_rusage have_rusage.o rusage_tmp have_rusage.h
${Q}echo 'forming have_rusage.h'
${Q}echo '/*' > have_rusage.h
${Q}echo ' * DO NOT EDIT -- generated by the Makefile' >> have_rusage.h
${Q}echo ' */' >> have_rusage.h
${Q}echo '' >> have_rusage.h
${Q}echo '' >> have_rusage.h
${Q}echo '#if !defined(__HAVE_RUSAGE_H__)' >> have_rusage.h
${Q}echo '#define __HAVE_RUSAGE_H__' >> have_rusage.h
${Q}echo '' >> have_rusage.h
${Q}echo '' >> have_rusage.h
${Q}echo '/* do we have or want getrusage()? */' >> have_rusage.h
-${Q}rm -f have_rusage.o have_rusage
-${Q}${LCC} ${ICFLAGS} ${HAVE_GETRUSAGE} have_rusage.c -c 2>/dev/null; \
true
-${Q}${LCC} ${ILDFLAGS} have_rusage.o -o have_rusage 2>/dev/null; true
-${Q}${SHELL} -c "./have_rusage > rusage_tmp 2>/dev/null" \
>/dev/null 2>&1; true
-${Q}if [ -s rusage_tmp ]; then \
cat rusage_tmp >> have_rusage.h; \
else \
echo '#undef HAVE_GETRUSAGE /* no */' >> have_rusage.h; \
fi
${Q}echo '' >> have_rusage.h
${Q}echo '' >> have_rusage.h
${Q}echo '#endif /* !__HAVE_RUSAGE_H__ */' >> have_rusage.h
-${Q}rm -f have_rusage have_rusage.o rusage_tmp
${Q}echo 'have_rusage.h formed'
-@if [ -z "${Q}" ]; then \
echo ''; \
echo '=-=-= start of $@ =-=-='; \
cat $@; \
echo '=-=-= end of $@ =-=-='; \
echo ''; \
else \
true; \
fi
have_strdup.h: have_strdup.c ${MAKE_FILE}
-${Q}rm -f have_strdup have_strdup.o strdup_tmp have_strdup.h
${Q}echo 'forming have_strdup.h'
${Q}echo '/*' > have_strdup.h
${Q}echo ' * DO NOT EDIT -- generated by the Makefile' >> have_strdup.h
${Q}echo ' */' >> have_strdup.h
${Q}echo '' >> have_strdup.h
${Q}echo '' >> have_strdup.h
${Q}echo '#if !defined(__HAVE_RUSAGE_H__)' >> have_strdup.h
${Q}echo '#define __HAVE_RUSAGE_H__' >> have_strdup.h
${Q}echo '' >> have_strdup.h
${Q}echo '' >> have_strdup.h
${Q}echo '/* do we have or want getstrdup()? */' >> have_strdup.h
-${Q}rm -f have_strdup.o have_strdup
-${Q}${LCC} ${ICFLAGS} ${HAVE_STRDUP} have_strdup.c -c 2>/dev/null; \
true
-${Q}${LCC} ${ILDFLAGS} have_strdup.o -o have_strdup 2>/dev/null; true
-${Q}${SHELL} -c "./have_strdup > strdup_tmp 2>/dev/null" \
>/dev/null 2>&1; true
-${Q}if [ -s strdup_tmp ]; then \
cat strdup_tmp >> have_strdup.h; \
else \
echo '#undef HAVE_STRDUP /* no */' >> have_strdup.h; \
fi
${Q}echo '' >> have_strdup.h
${Q}echo '' >> have_strdup.h
${Q}echo '#endif /* !__HAVE_RUSAGE_H__ */' >> have_strdup.h
-${Q}rm -f have_strdup have_strdup.o strdup_tmp
${Q}echo 'have_strdup.h formed'
-@if [ -z "${Q}" ]; then \
echo ''; \
echo '=-=-= start of $@ =-=-='; \
cat $@; \
echo '=-=-= end of $@ =-=-='; \
echo ''; \
else \
true; \
fi
args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h
-${Q}rm -f args.h have_args
${Q}echo 'forming args.h'
@@ -2147,98 +2232,6 @@ args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h
true; \
fi
calc_errno.h: calc_errno.c ${MAKE_FILE}
-${Q}rm -f calc_errno.h calc_errno calc_errno_tmp
${Q}echo 'forming calc_errno.h'
${Q}echo '/*' > calc_errno.h
${Q}echo ' * DO NOT EDIT -- generated by the Makefile' >> calc_errno.h
${Q}echo ' */' >> calc_errno.h
${Q}echo '' >> calc_errno.h
${Q}echo '' >> calc_errno.h
${Q}echo '#if !defined(__CALC_ERRNO_H__)' >> calc_errno.h
${Q}echo '#define __CALC_ERRNO_H__' >> calc_errno.h
${Q}echo '' >> calc_errno.h
${Q}echo '' >> calc_errno.h
-${Q}if [ X"${ERRNO_DECL}" = X"-DERRNO_NO_DECL" ]; then \
echo '/*' >> calc_errno.h; \
echo ' * The calc Makefile explicitly told us' >> calc_errno.h; \
echo ' * how to declare errno and friends.' >> calc_errno.h; \
echo ' */' >> calc_errno.h; \
echo '' >> calc_errno.h; \
echo '#include <stdio.h>' >> calc_errno.h; \
echo '#include <errno.h>' >> calc_errno.h; \
elif [ X"${ERRNO_DECL}" = X"-DERRNO_STD_DECL" ]; then \
echo '/*' >> calc_errno.h; \
echo ' * The calc Makefile explicitly told us' >> calc_errno.h; \
echo ' * how to declare errno and friends.' >> calc_errno.h; \
echo ' */' >> calc_errno.h; \
echo '' >> calc_errno.h; \
echo 'extern int errno; ' \
'/* last system error */' >> calc_errno.h; \
echo 'extern const char *const sys_errlist[];' \
' /* system error messages*/' >> calc_errno.h; \
echo 'extern int sys_nerr; ' \
'/* number of system errors */' >> calc_errno.h; \
elif [ X"${ERRNO_DECL}" = X"-DERRNO_OLD_DECL" ]; then \
echo '/*' >> calc_errno.h; \
echo ' * The calc Makefile explicitly told us' >> calc_errno.h; \
echo ' * how to declare errno and friends.' >> calc_errno.h; \
echo ' */' >> calc_errno.h; \
echo '' >> calc_errno.h; \
echo 'extern int errno; ' \
'/* last system error */' >> calc_errno.h; \
echo 'extern char *sys_errlist[];' \
' /* system error messages*/' >> calc_errno.h; \
echo 'extern int sys_nerr; ' \
'/* number of system errors */' >> calc_errno.h; \
else \
${LCC} ${ICFLAGS} -DTRY_ERRNO_NO_DECL \
calc_errno.c -o calc_errno 2>calc_errno_tmp; \
if [ -x ./calc_errno ]; then \
./calc_errno >> calc_errno.h; \
else \
${LCC} ${ICFLAGS} -DTRY_ERRNO_STD_DECL \
calc_errno.c -o calc_errno 2>calc_errno_tmp; \
if [ -x ./calc_errno ]; then \
./calc_errno >> calc_errno.h; \
else \
${LCC} ${ICFLAGS} -DTRY_ERRNO_OLD_DECL \
calc_errno.c -o calc_errno 2>calc_errno_tmp; \
if [ -x ./calc_errno ]; then \
./calc_errno >> calc_errno.h; \
else \
echo '/*' >> calc_errno.h; \
echo ' * We were unable to to determine' >> calc_errno.h; \
echo ' * how to declare errno and friends.' >> calc_errno.h; \
echo ' * So we will guess this will work' >> calc_errno.h; \
echo ' * and hope for the best.' >> calc_errno.h; \
echo ' */' >> calc_errno.h; \
echo '' >> calc_errno.h; \
echo 'extern int errno; ' \
'/* last system error */' >> calc_errno.h; \
echo 'extern const char *const sys_errlist[];' \
' /* system error messages*/' >> calc_errno.h; \
echo 'extern int sys_nerr; ' \
'/* number of system errors */' >> calc_errno.h; \
fi; \
fi; \
fi; \
fi
${Q}echo '' >> calc_errno.h
${Q}echo '' >> calc_errno.h
${Q}echo '#endif /* !__CALC_ERRNO_H__ */' >> calc_errno.h
-${Q}rm -f calc_errno calc_errno_tmp
${Q}echo 'calc_errno.h formed'
-@if [ -z "${Q}" ]; then \
echo ''; \
echo '=-=-= start of $@ =-=-='; \
cat $@; \
echo '=-=-= end of $@ =-=-='; \
echo ''; \
else \
true; \
fi
calcerr.h: calcerr.tbl calcerr_h.sed calcerr_h.awk ${MAKE_FILE}
-${Q}rm -f calerr.h
${Q}echo 'forming calcerr.h'
@@ -2319,27 +2312,21 @@ longbits: longbits.o
lib/.all:
${V} echo '=-=-=-=-= start of $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking all rule for lib =-=-=-=-='
cd lib; ${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} all
cd lib; ${MAKE} -f Makefile ${LIB_PASSDOWN} all
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-='
help/.all:
${V} echo '=-=-=-=-= start of $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking all rule for help =-=-=-=-='
cd help; ${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} all
cd help; ${MAKE} -f Makefile ${HELP_PASSDOWN} all
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-='
help/builtin: func.c help/builtin.top help/builtin.end help/funclist.sed
${V} echo '=-=-=-=-= start of $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking builtin rule for help =-=-=-=-='
cd help; ${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} builtin
cd help; ${MAKE} -f Makefile ${HELP_PASSDOWN} builtin
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-='
@@ -2439,9 +2426,7 @@ bsdi: ${LIB_H_SRC} ${BUILD_H_SRC} calc.1
echo chmod 0444 gen_h/$$i; \
chmod 0444 gen_h/$$i; \
done
cd help; ${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} bsdi
cd help; ${MAKE} -f Makefile ${HELP_PASSDOWN} bsdi
${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-='
##
@@ -2552,25 +2537,29 @@ distlist: ${DISTLIST}
${Q}(for i in ${DISTLIST}; do \
echo $$i; \
done; \
(cd help; ${MAKE} distlist \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} SORT=${SORT}); \
(cd lib; ${MAKE} distlist \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} SORT=${SORT}); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} distlist); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} distlist)) | ${SORT}
(cd help; ${MAKE} ${HELP_PASSDOWN} $@); \
(cd lib; ${MAKE} ${LIB_PASSDOWN} $@); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} $@); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} $@)) | ${SORT}
distdir:
${Q}(echo .; \
(cd help; ${MAKE} distdir \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} SORT=${SORT}); \
(cd lib; ${MAKE} distdir \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} SORT=${SORT}); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} distdir); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} distdir)) | ${SORT}
(cd help; ${MAKE} ${HELP_PASSDOWN} $@); \
(cd lib; ${MAKE} ${LIB_PASSDOWN} $@); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} $@); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} $@)) | ${SORT}
calcliblist:
${Q}(for i in ${CALCLIBLIST}; do \
echo $$i; \
done; \
(cd help; ${MAKE} ${HELP_PASSDOWN} $@); \
(cd lib; ${MAKE} ${LIB_PASSDOWN} $@); \
(cd custom; ${MAKE} ${CUSTOM_PASSDOWN} $@); \
(cd sample; ${MAKE} ${SAMPLE_PASSDOWN} $@)) | ${SORT}
calcliblistfmt:
${Q}${MAKE} calcliblist | ${FMT} -64 | ${SED} -e 's/^/ /'
##
#
@@ -2584,10 +2573,10 @@ distdir:
#
##
check: all ./lib/regress.cal ${REGRESS_CAL}
check: all ./lib/regress.cal
${CALC_ENV} ./calc -d -q read regress
chk: ./lib/regress.cal ${REGRESS_CAL}
chk: ./lib/regress.cal
${V} echo '=-=-=-=-= start of $@ rule =-=-=-=-='
${CALC_ENV} ./calc -d -q read regress 2>&1 | ${AWK} -f check.awk
${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-='
@@ -2630,7 +2619,6 @@ env:
@echo "HAVE_GETPRID=${HAVE_GETPRID}"; echo ""
@echo "HAVE_URANDOM=${HAVE_URANDOM}"; echo ""
@echo "ALIGN32=${ALIGN32}"; echo ""
@echo "ERRNO_DECL=${ERRNO_DECL}"; echo ""
@echo "BINDIR=${BINDIR}"; echo ""
@echo "TOPDIR=${TOPDIR}"; echo ""
@echo "LIBDIR=${LIBDIR}"; echo ""
@@ -2646,7 +2634,6 @@ env:
@echo "MANMAKE=${MANMAKE}"; echo ""
@echo "CALCPATH=${CALCPATH}"; echo ""
@echo "CALCRC=${CALCRC}"; echo ""
@echo "CALCBINDINGS=${CALCBINDINGS}"; echo ""
@echo "CALCPAGER=${CALCPAGER}"; echo ""
@echo "DEBUG=${DEBUG}"; echo ""
@echo "NO_SHARED=${NO_SHARED}"; echo ""
@@ -2692,9 +2679,10 @@ env:
@echo "UTIL_TMP=${UTIL_TMP}"; echo ""
@echo "UTIL_PROGS=${UTIL_PROGS}"; echo ""
@echo "LIB_H_SRC=${LIB_H_SRC}"; echo ""
@echo "REGRESS_CAL=${REGRESS_CAL}"; echo ""
@echo "CUSTOM_PASSDOWN=${CUSTOM_PASSDOWN}"; echo ""
@echo "SAMPLE_PASSDOWN=${SAMPLE_PASSDOWN}"; echo ""
@echo "HELP_PASSDOWN=${HELP_PASSDOWN}"; echo ""
@echo "LIB_PASSDOWN=${LIB_PASSDOWN}"; echo ""
@echo "H_SRC=${H_SRC}"; echo ""
@echo "C_SRC=${C_SRC}"; echo ""
@echo "DISTLIST=${DISTLIST}"; echo ""
@@ -2792,14 +2780,10 @@ clean:
-rm -f ${UTIL_PROGS}
-rm -f .libcustcalc_error
${Q}echo '=-=-=-=-= Invoking $@ rule for help =-=-=-=-='
-cd help; ${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} clean
-cd help; ${MAKE} -f Makefile ${HELP_PASSDOWN} clean
${Q}echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${Q}echo '=-=-=-=-= Invoking $@ rule for lib =-=-=-=-='
-cd lib; ${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} clean
-cd lib; ${MAKE} -f Makefile ${LIB_PASSDOWN} clean
${Q}echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking $@ rule for custom =-=-=-=-='
cd custom; ${MAKE} -f Makefile ${CUSTOM_PASSDOWN} clean
@@ -2807,7 +2791,6 @@ clean:
${V} echo '=-=-=-=-= Invoking $@ rule for sample =-=-=-=-='
cd sample; ${MAKE} -f Makefile ${SAMPLE_PASSDOWN} clean
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
-rm -f funclist.o funclist.c
${Q}echo remove files that are obsolete
-rm -f endian.h stdarg.h libcalcerr.a lib/obj help/obj
-rm -f have_vs.c std_arg.h try_stdarg.c fnvhash.c
@@ -2830,14 +2813,10 @@ clobber: lintclean
-rm -f calc.pixie calc.rf calc.Counts calc.cord
-rm -rf gen_h skel Makefile.bak
${V} echo '=-=-=-=-= Invoking $@ rule for help =-=-=-=-='
-cd help;${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} clobber
-cd help; ${MAKE} -f Makefile ${HELP_PASSDOWN} clobber
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking $@ rule for lib =-=-=-=-='
-cd lib; ${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} clobber
-cd lib; ${MAKE} -f Makefile ${LIB_PASSDOWN} clobber
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking $@ rule for custom =-=-=-=-='
cd custom; ${MAKE} -f Makefile ${CUSTOM_PASSDOWN} clobber
@@ -2873,6 +2852,20 @@ install: calc libcalc.a ${LIB_H_SRC} ${BUILD_H_SRC} calc.1
true; \
fi
-chmod 0755 ${HELPDIR}
-${Q}if [ ! -d ${INCDIR} ]; then \
echo mkdir ${INCDIR}; \
mkdir ${INCDIR}; \
else \
true; \
fi
-chmod 0755 ${INCDIR}
-${Q}if [ ! -d ${INCDIRCALC} ]; then \
echo mkdir ${INCDIRCALC}; \
mkdir ${INCDIRCALC}; \
else \
true; \
fi
-chmod 0755 ${INCDIRCALC}
-${Q}if [ ! -d ${BINDIR} ]; then \
echo mkdir ${BINDIR}; \
mkdir ${BINDIR}; \
@@ -2884,14 +2877,10 @@ install: calc libcalc.a ${LIB_H_SRC} ${BUILD_H_SRC} calc.1
cp calc ${BINDIR}
-chmod 0555 ${BINDIR}/calc
${V} echo '=-=-=-=-= Invoking $@ rule for help =-=-=-=-='
cd help; ${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} install
cd help; ${MAKE} -f Makefile ${HELP_PASSDOWN} install
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking $@ rule for lib =-=-=-=-='
cd lib; ${MAKE} -f Makefile \
MAKE_FILE=${MAKE_FILE} TOPDIR=${TOPDIR} LIBDIR=${LIBDIR} \
HELPDIR=${HELPDIR} install
cd lib; ${MAKE} -f Makefile ${LIB_PASSDOWN} install
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking $@ rule for custom =-=-=-=-='
cd custom; ${MAKE} -f Makefile ${CUSTOM_PASSDOWN} install
@@ -2900,16 +2889,18 @@ install: calc libcalc.a ${LIB_H_SRC} ${BUILD_H_SRC} calc.1
cd sample; ${MAKE} -f Makefile ${SAMPLE_PASSDOWN} install
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
-rm -f ${LIBDIR}/libcalc.a
cp libcalc.a ${LIBDIR}/libcalc.a
-chmod 0644 ${LIBDIR}/libcalc.a
cp -f libcalc.a ${LIBDIR}/libcalc.a
${RANLIB} ${LIBDIR}/libcalc.a
-chmod 0644 ${LIBDIR}/libcalc.a
-${Q}for i in ${LIB_H_SRC} ${BUILD_H_SRC}; do \
echo rm -f ${LIBDIR}/$$i; \
rm -f ${LIBDIR}/$$i; \
echo cp $$i ${LIBDIR}; \
cp $$i ${LIBDIR}; \
echo chmod 0444 ${LIBDIR}/$$i; \
chmod 0444 ${LIBDIR}/$$i; \
echo rm -f ${INCDIRCALC}/$$i; \
rm -f ${INCDIRCALC}/$$i; \
echo cp $$i ${INCDIRCALC}; \
cp $$i ${INCDIRCALC}; \
echo chmod 0444 ${INCDIRCALC}/$$i; \
chmod 0444 ${INCDIRCALC}/$$i; \
done
${Q}: If lint was made, install the lint library.
-${Q}if [ -f llib-lcalc.ln ]; then \
@@ -2952,6 +2943,9 @@ install: calc libcalc.a ${LIB_H_SRC} ${BUILD_H_SRC} calc.1
-rm -f ${LIBDIR}/stdarg.h stdarg.h
-rm -f ${LIBDIR}/prototype.h prototype.h
-rm -f ${LIBDIR}/libcalcerr.a libcalcerr.a
-rm -f ${LIBDIR}/calc_errno.h calc_errno.h ${INCDIRCALC}/calc_errno.h
-rm -f calc_errno.c calc_errno.o calc_errno
-rm -f ${LIBDIR}/altbind ${HELPDIR}/altbind
${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-='
##
@@ -2973,6 +2967,7 @@ addop.o: config.h
addop.o: endian_calc.h
addop.o: func.h
addop.o: hash.h
addop.o: have_const.h
addop.o: have_malloc.h
addop.o: have_memmv.h
addop.o: have_newstr.h
@@ -3029,6 +3024,7 @@ blkcpy.o: config.h
blkcpy.o: endian_calc.h
blkcpy.o: file.h
blkcpy.o: hash.h
blkcpy.o: have_const.h
blkcpy.o: have_fpos.h
blkcpy.o: have_malloc.h
blkcpy.o: have_memmv.h
@@ -3117,7 +3113,6 @@ calc.o: symbol.h
calc.o: token.h
calc.o: value.h
calc.o: zmath.h
calc_errno.o: calc_errno.c
calcerr.o: calcerr.c
calcerr.o: calcerr.h
calcerr.o: have_const.h
@@ -3133,6 +3128,7 @@ codegen.o: config.h
codegen.o: endian_calc.h
codegen.o: func.h
codegen.o: hash.h
codegen.o: have_const.h
codegen.o: have_malloc.h
codegen.o: have_memmv.h
codegen.o: have_newstr.h
@@ -3217,6 +3213,7 @@ const.o: config.h
const.o: const.c
const.o: endian_calc.h
const.o: hash.h
const.o: have_const.h
const.o: have_malloc.h
const.o: have_memmv.h
const.o: have_newstr.h
@@ -3271,6 +3268,7 @@ file.o: file.c
file.o: file.h
file.o: fposval.h
file.o: hash.h
file.o: have_const.h
file.o: have_fpos.h
file.o: have_malloc.h
file.o: have_memmv.h
@@ -3295,7 +3293,6 @@ func.o: alloc.h
func.o: block.h
func.o: byteswap.h
func.o: calc.h
func.o: calc_errno.h
func.o: calcerr.h
func.o: cmath.h
func.o: config.h
@@ -3368,9 +3365,11 @@ have_newstr.o: have_newstr.c
have_offscl.o: have_offscl.c
have_posscl.o: have_fpos.h
have_posscl.o: have_posscl.c
have_rusage.o: have_rusage.c
have_stdvs.o: have_stdvs.c
have_stdvs.o: have_string.h
have_stdvs.o: have_unistd.h
have_strdup.o: have_strdup.c
have_uid_t.o: have_uid_t.c
have_uid_t.o: have_unistd.h
have_ustat.o: have_ustat.c
@@ -3387,6 +3386,7 @@ help.o: conf.h
help.o: config.h
help.o: endian_calc.h
help.o: hash.h
help.o: have_const.h
help.o: have_malloc.h
help.o: have_memmv.h
help.o: have_newstr.h
@@ -3412,10 +3412,12 @@ hist.o: cmath.h
hist.o: config.h
hist.o: endian_calc.h
hist.o: hash.h
hist.o: have_const.h
hist.o: have_malloc.h
hist.o: have_memmv.h
hist.o: have_newstr.h
hist.o: have_stdlib.h
hist.o: have_strdup.h
hist.o: have_string.h
hist.o: have_unistd.h
hist.o: hist.c
@@ -3440,11 +3442,13 @@ input.o: conf.h
input.o: config.h
input.o: endian_calc.h
input.o: hash.h
input.o: have_const.h
input.o: have_malloc.h
input.o: have_memmv.h
input.o: have_newstr.h
input.o: have_stdlib.h
input.o: have_string.h
input.o: have_unistd.h
input.o: hist.h
input.o: input.c
input.o: longbits.h
@@ -3469,6 +3473,7 @@ label.o: config.h
label.o: endian_calc.h
label.o: func.h
label.o: hash.h
label.o: have_const.h
label.o: have_malloc.h
label.o: have_memmv.h
label.o: have_newstr.h
@@ -3503,6 +3508,7 @@ lib_calc.o: have_malloc.h
lib_calc.o: have_memmv.h
lib_calc.o: have_newstr.h
lib_calc.o: have_stdlib.h
lib_calc.o: have_strdup.h
lib_calc.o: have_string.h
lib_calc.o: have_unistd.h
lib_calc.o: label.h
@@ -3598,6 +3604,7 @@ math_error.o: cmath.h
math_error.o: config.h
math_error.o: endian_calc.h
math_error.o: hash.h
math_error.o: have_const.h
math_error.o: have_malloc.h
math_error.o: have_memmv.h
math_error.o: have_newstr.h
@@ -3648,6 +3655,7 @@ obj.o: config.h
obj.o: endian_calc.h
obj.o: func.h
obj.o: hash.h
obj.o: have_const.h
obj.o: have_malloc.h
obj.o: have_memmv.h
obj.o: have_newstr.h
@@ -3861,6 +3869,7 @@ seed.o: have_gettime.h
seed.o: have_malloc.h
seed.o: have_memmv.h
seed.o: have_newstr.h
seed.o: have_rusage.h
seed.o: have_stdlib.h
seed.o: have_string.h
seed.o: have_urandom.h
@@ -3952,6 +3961,7 @@ string.o: cmath.h
string.o: config.h
string.o: endian_calc.h
string.o: hash.h
string.o: have_const.h
string.o: have_malloc.h
string.o: have_memmv.h
string.o: have_newstr.h
@@ -3977,6 +3987,7 @@ symbol.o: config.h
symbol.o: endian_calc.h
symbol.o: func.h
symbol.o: hash.h
symbol.o: have_const.h
symbol.o: have_malloc.h
symbol.o: have_memmv.h
symbol.o: have_newstr.h
@@ -4006,6 +4017,7 @@ token.o: cmath.h
token.o: config.h
token.o: endian_calc.h
token.o: hash.h
token.o: have_const.h
token.o: have_malloc.h
token.o: have_memmv.h
token.o: have_newstr.h
@@ -4065,6 +4077,7 @@ version.o: cmath.h
version.o: config.h
version.o: endian_calc.h
version.o: hash.h
version.o: have_const.h
version.o: have_malloc.h
version.o: have_memmv.h
version.o: have_newstr.h

14
README
View File

@@ -74,7 +74,9 @@ for a wish/todo list. Code contributions are welcome.
To join the calc-tester mailing list. Send a request to:
calc-tester-request@postofc.corp.sgi.com
calc-tester-request at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
Your message body (not the subject) should consist of:
@@ -85,6 +87,14 @@ Your message body (not the subject) should consist of:
where ``address'' is your EMail address and ``your_full_name'' is
your full name.
Calc bug reports, however should be sent to:
calc-bugs at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
but see the BUGS file first.
The calc web site is located at:
http://reality.sgi.com/chongo/tech/comp/calc
http://reality.sgi.com/chongo/tech/comp/calc/

92
addop.c
View File

@@ -22,6 +22,7 @@
static long maxopcodes; /* number of opcodes available */
static long newindex; /* index of new function */
static char *newname; /* name of new function */
static long oldop; /* previous opcode */
static long oldoldop; /* opcode before previous opcode */
static long debugline; /* line number of latest debug opcode */
@@ -61,26 +62,49 @@ initfunctions(void)
void
showfunctions(void)
{
FUNC **fpp; /* pointer into function table */
FUNC *fp; /* current function */
long count;
long index;
count = 0;
if (funccount > 0) {
for (fpp = &functions[funccount - 1]; fpp >= functions; fpp--) {
fp = *fpp;
if (conf->lib_debug & LIBDBG_FUNC_INFO)
math_str("Index\tName \tArgs\tOpcodes\n"
"-----\t------ \t---- \t------\n");
else
math_str("Name\tArguments\n"
"----\t---------\n");
for (index = 0; index < funccount; index++) {
fp = functions[index];
if (conf->lib_debug & LIBDBG_FUNC_INFO) {
math_fmt("%5ld\t%-12s\t", index,
namestr(&funcnames,index));
if (fp) {
count++;
math_fmt("%-5d\t%-5ld\n",
fp->f_paramcount, fp->f_opcodecount);
} else {
math_str("null\t0\n");
}
} else {
if (fp == NULL)
continue;
if (count++ == 0) {
printf("Name Arguments\n---- ---------\n");
}
printf("%-12s %-2d\n", fp->f_name, fp->f_paramcount);
count++;
math_fmt("%-12s\t%-2d\n", namestr(&funcnames,
index), fp->f_paramcount);
}
}
if (count > 0) {
printf("\nNumber: %ld\n", count);
}
if (conf->lib_debug & LIBDBG_FUNC_INFO) {
math_fmt("\nNumber non-null: %ld\n", count);
math_fmt("Number null: %ld\n", funccount - count);
math_fmt("Total number: %ld\n", funccount);
} else {
printf("No user functions defined\n");
if (count > 0)
math_fmt("\nNumber: %ld\n", count);
else
math_str("No user functions defined\n");
}
}
@@ -114,7 +138,9 @@ beginfunc(char *name, BOOL newflag)
fp->f_localcount = 0;
fp->f_opcodecount = 0;
fp->f_savedvalue.v_type = V_NULL;
fp->f_name = namestr(&funcnames, newindex);
fp->f_savedvalue.v_subtype = V_NOSUBTYPE;
newname = namestr(&funcnames, newindex);
fp->f_name = newname;
curfunc = fp;
initlocals();
initlabels();
@@ -141,10 +167,11 @@ endfunc(void)
addop(OP_UNDEF);
addop(OP_RETURN);
}
checklabels();
if (errorcount) {
freefunc(curfunc);
printf("\"%s\": %ld error%s\n", curfunc->f_name, errorcount,
printf("\"%s\": %ld error%s\n", newname, errorcount,
((errorcount == 1) ? "" : "s"));
return;
}
@@ -166,7 +193,7 @@ endfunc(void)
}
if ((inputisterminal() && conf->lib_debug & LIBDBG_STDIN_FUNC) ||
(!inputisterminal() && conf->lib_debug & LIBDBG_FILE_FUNC)) {
printf("%s(", fp->f_name);
printf("%s(", newname);
for (index = 0; index < fp->f_paramcount; index++) {
if (index)
putchar(',');
@@ -230,7 +257,7 @@ rmuserfunc(char *name)
index = findstr(&funcnames, name);
if (index < 0) {
printf("%s() has never been defined\n",
fprintf(stderr, "%s() has never been defined\n",
name);
return;
}
@@ -251,12 +278,25 @@ rmuserfunc(char *name)
void
freefunc(FUNC *fp)
{
long index;
long i;
if (fp == NULL)
return;
if (fp == curfunc) {
index = newindex;
} else {
for (index = 0; index < funccount; index++) {
if (functions[index] == fp)
break;
}
if (index == funccount) {
math_error("Bad call to freefunc!!!");
/*NOTREACHED*/
}
}
if (conf->traceflags & TRACE_FNCODES) {
printf("Freeing function \"%s\"\n", fp->f_name);
printf("Freeing function \"%s\"\n",namestr(&funcnames,index));
dumpnames = FALSE;
for (i = 0; i < fp->f_opcodecount; ) {
printf("%ld: ", i);
@@ -272,12 +312,14 @@ freefunc(FUNC *fp)
void
rmalluserfunc(void)
{
FUNC **fpp;
FUNC *fp;
long index;
for (fpp = functions; fpp < &functions[funccount]; fpp++) {
if (*fpp) {
freefunc(*fpp);
*fpp = NULL;
for (index = 0; index < funccount; index++) {
fp = functions[index];
if (fp) {
freefunc(fp);
functions[index] = NULL;
}
}
}
@@ -461,7 +503,8 @@ addop(long op)
fp->f_opcodecount -= diff;
oldop = OP_NOP;
oldoldop = OP_NOP;
fprintf(stderr, "%ld: unused value ignored\n",
fprintf(stderr,
"Line %ld: unused value ignored\n",
linenumber());
return;
}
@@ -534,8 +577,7 @@ addop(long op)
qfree(q);
fp->f_opcodes[count - 2] = OP_ZERO;
fp->f_opcodecount--;
}
else if (qisone(q)) {
} else if (qisone(q)) {
qfree(q);
fp->f_opcodes[count - 2] = OP_ONE;
fp->f_opcodecount--;
@@ -638,5 +680,3 @@ addoplabel(long op, LABEL *label)
addop(op);
uselabel(label);
}
/* END CODE */

View File

@@ -4,7 +4,7 @@
* This file was written by:
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*

View File

@@ -47,8 +47,8 @@ associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
QCKHASH hash;
int i;
if (dim <= 0) {
math_error("No dimensions for indexing association");
if (dim < 0) {
math_error("Negative dimension for indexing association");
/*NOTREACHED*/
}
@@ -80,6 +80,7 @@ associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
*/
if (!create) {
val.v_type = V_NULL;
val.v_subtype = V_NOSUBTYPE;
return &val;
}
@@ -216,6 +217,27 @@ assocfindex(ASSOC *ap, long index)
}
/*
* Returns the list of indices for an association element with specified
* double-bracket index.
*/
LIST *
associndices(ASSOC *ap, long index)
{
ASSOCELEM *ep;
LIST *lp;
int i;
ep = elemindex(ap, index);
if (ep == NULL)
return NULL;
lp = listalloc();
for (i = 0; i < ep->e_dim; i++)
insertlistlast(lp, &ep->e_indices[i]);
return lp;
}
/*
* Compare two associations to see if they are identical.
* Returns TRUE if they are different.
@@ -244,8 +266,7 @@ assoccmp(ASSOC *ap1, ASSOC *ap2)
hash = ep1->e_hash;
dim = ep1->e_dim;
for (ep2 = ap2->a_table[hash % size2]; ;
ep2 = ep2->e_next)
{
ep2 = ep2->e_next) {
if (ep2 == NULL)
return TRUE;
if (ep2->e_hash != hash)
@@ -282,8 +303,7 @@ assoccopy(ASSOC *oldap)
for (oldhi = 0; oldhi < oldap->a_size; oldhi++) {
for (oldep = oldap->a_table[oldhi]; oldep;
oldep = oldep->e_next)
{
oldep = oldep->e_next) {
ep = (ASSOCELEM *) malloc(ELEMSIZE(oldep->e_dim));
if (ep == NULL) {
math_error("Cannot allocate association element");
@@ -292,6 +312,7 @@ assoccopy(ASSOC *oldap)
ep->e_dim = oldep->e_dim;
ep->e_hash = oldep->e_hash;
ep->e_value.v_type = V_NULL;
ep->e_value.v_subtype = V_NOSUBTYPE;
for (i = 0; i < ep->e_dim; i++)
copyvalue(&oldep->e_indices[i], &ep->e_indices[i]);
copyvalue(&oldep->e_value, &ep->e_value);
@@ -447,8 +468,7 @@ assocprint(ASSOC *ap, long max_print)
((ap->a_count == 1) ? "" : "s"));
for (index = 0; ((index < max_print) && (index < ap->a_count));
index++)
{
index++) {
ep = elemindex(ap, index);
if (ep == NULL)
continue;
@@ -489,5 +509,3 @@ compareindices(VALUE *v1, VALUE *v2, long dim)
return TRUE;
}
/* END CODE */

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*/
#include <stdio.h>
@@ -330,6 +330,7 @@ copyblk2mat(BLOCK *blk, long ssi, long num, MATRIX *dmat, long dsi)
i = num;
while (i-- > 0) {
vp->v_type = V_NUM;
vp->v_subtype = V_NOSUBTYPE;
vp->v_num = itoq((long) *op++);
vp++;
}

11
block.c
View File

@@ -28,7 +28,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/
@@ -479,7 +479,7 @@ blk_print(BLOCK *blk)
BOOL havetail;
USB8 *ptr;
/* XXX - use the config parameters for better print control */
/* XXX - should use the config parameters for better print control */
printf("chunksize = %d, maxsize = %d, datalen = %d\n\t",
(int)blk->blkchunk, (int)blk->maxsize, (int)blk->datalen);
@@ -512,9 +512,9 @@ nblock_print(NBLOCK *nblk)
printf("chunksize = %d, maxsize = %d, datalen = %d\n\t",
(int)blk->blkchunk, (int)blk->maxsize, (int)blk->datalen);
printf("NULL");
}
else
} else {
blk_print(blk);
}
}
@@ -556,8 +556,7 @@ reallocnblock(int id, int len, int chunk)
math_error("Allocation failed");
/*NOTREACHED*/
}
}
else if (newsize != oldsize) {
} else if (newsize != oldsize) {
newdata = realloc(blk->data, newsize);
if (newdata == NULL) {
math_error("Reallocation failed");

View File

@@ -28,7 +28,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

9
calc.c
View File

@@ -39,9 +39,6 @@
/*
* static definitions and functions
*/
static char *usage = "usage: %s [-c] [-C] [-d] [-e] [-h] [-i] [-m mode]\n"
"\t[-D calc_debug[:lib_debug:[user_debug]]]\n"
"\t[-n] [-p] [-q] [-u] [-v] [[--] calc_cmd ...]\n";
static void intint(int arg); /* interrupt routine */
@@ -153,7 +150,11 @@ main(int argc, char **argv)
* we are too early in processing to call
* libcalc_call_me_last() - nothing to cleanup
*/
fprintf(stderr, usage, program);
fprintf(stderr,
"usage: %s [-c] [-C] [-d] [-e] [-h] [-i] [-m mode]\n"
"\t[-D calc_debug[:lib_debug:[user_debug]]]\n"
"\t[-n] [-p] [-q] [-u] [-v] [[--] calc_cmd ...]\n",
program);
exit(1);
}
}

6
calc.h
View File

@@ -14,16 +14,19 @@
#include "value.h"
#include "have_const.h"
/*
* Configuration definitions
*/
#define CALCPATH "CALCPATH" /* environment variable for files */
#define CALCRC "CALCRC" /* environment variable for startup */
#define CALCBINDINGS "CALCBINDINGS" /* environment variable for hist bindings */
#define CALCBINDINGS "CALCBINDINGS" /* env variable for hist bindings */
#define HOME "HOME" /* environment variable for home dir */
#define PAGER "PAGER" /* environment variable for help */
#define SHELL "SHELL" /* environment variable for shell */
#define DEFAULTCALCBINDINGS "bindings" /* default calc bindings file */
#define DEFAULTCALCHELP "help" /* help file that -h prints */
#define DEFAULTSHELL "sh" /* default shell to use */
#define CALCEXT ".cal" /* extension for files read in */
@@ -140,6 +143,7 @@ extern void givehelp(char *type);
extern void libcalc_call_me_first(void);
extern void libcalc_call_me_last(void);
extern void showerrors(void);
extern char *calc_strdup(CONST char *);
/*
* Initialization

View File

@@ -555,9 +555,10 @@ line, or \fI\-m\fP disallows opening files for reading),
reads
key bindings from the filename specified
by this environment variable.
.br
The key binding file is searched for along the $CALCPATH list
of directories.
.sp
Default value: ${CALCBINDINGS}
Default value: binding
.sp
This variable is not used if calc was compiled with GNU-readline support.
In that case, the standard readline mechanisms (see readline(3)) are used.
@@ -570,7 +571,11 @@ The majority of
was written by David I. Bell.
.sp
.B Calc
archives and calc-tester mailing list maintained by Landon Curt Noll.
The Calc primary mirror, calc mailing list and calc bug report
processing is performed by Landon Curt Noll.
.sp
Landon Curt Noll maintains the master reference source, performs
release control functions as well as other calc maintenance functions.
.sp
Thanks for suggestions and encouragement from Peter Miller,
Neil Justusson, and Landon Noll.
@@ -610,15 +615,42 @@ scripts that you would like you see included
in future distributions to:
.sp
.in +0.5i
calc-tester@postofc.corp.sgi.com
.nf
calc-tester at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
.fi
.in -0.5i
.sp
Bug reports are sent to:
.in +0.5i
.nf
calc-bugs at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
.fi
.in -0.5i
.sp
See the
.I BUGS
source file or use the
.I calc
command:
.sp
.in +0.5i
.nf
help bugs
.fi
.in -0.5i
.sp
for more information about bug reporting.
.sp
Landon Noll maintains the the
.B calc
web site is located at:
.sp
.in +0.5i
http://reality.sgi.com/chongo/tech/comp/calc
http://reality.sgi.com/chongo/tech/comp/calc/
.in -0.5i
.sp
One may join the
@@ -626,7 +658,11 @@ One may join the
testing group by sending a request to:
.sp
.in +0.5i
calc-tester-request@postofc.corp.sgi.com
.nf
calc-tester-request at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
.fi
.in -0.5i
.sp
Your message body (not the subject) should consist of:

View File

@@ -1,123 +0,0 @@
/*
* errno - Determine how to declare errno, sys_errlist and sys_nerr
*
* On most machines: errno sys_errlist and sys_nerr are declared
* by either <stdio.h> and/or <errno.h>. But some systems declare
* them somewhere else or do not declare them at all!
*
* If the system were doing a proper job in headers, this should declare them:
*
* #include <stdio.h>
* #include <errno.h>
*
* But one some systems one must explicitly declare them as:
*
* extern int errno;
* extern const char *const sys_errlist[];
* extern int sys_nerr;
*
* and on some old systems they must be explicitly and incorrectly declared as:
*
* extern int errno;
* extern char *sys_errlist[];
* extern int sys_nerr;
*
* The purpose of this utility is try and find the right way to declare
* them and to output the middle of a header file called calc_errno.h.
*/
/*
* Copyright (c) 1999 by Landon Curt Noll. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright, this permission notice and text
* this comment, and the disclaimer below appear in all of the following:
*
* supporting documentation
* source copies
* source works derived from this source
* binaries derived from this source or from derived source
*
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* chongo was here /\../\
*/
#include <stdio.h>
#if defined(TRY_ERRNO_NO_DECL)
# include <errno.h>
#endif /* TRY_ERRNO_NO_DECL */
int
main(void)
{
#if defined(TRY_ERRNO_NO_DECL)
printf("/*\n");
printf(" * The following comments were produced by calc_errno\n");
printf(" * in an effort to see if these values were correctly\n");
printf(" * declared when calc_errno.c was compiled.\n");
printf(" */\n\n");
printf("/* Initially errno is %d */\n", errno);
printf("/* There are %d entries in sys_errlist[] */\n", sys_nerr);
printf("/* The 2nd sys_errlist entry is \"%s\" */\n\n", sys_errlist[1]);
printf("/*\n");
printf(" * Based on the above, calc_errno now knows\n");
printf(" * how to declare errno and friends.\n");
printf(" */\n\n");
printf("#include <stdio.h>\n");
printf("#include <errno.h>\n");
#elif defined(TRY_ERRNO_OLD_DECL)
extern int errno; /* last system error */
extern char *sys_errlist[]; /* system error messages */
extern int sys_nerr; /* number of system errors*/
printf("/*\n");
printf(" * The following comments were produced by calc_errno\n");
printf(" * in an effort to see if these values were correctly\n");
printf(" * declared when calc_errno.c was compiled.\n");
printf(" */\n\n");
printf("/* Initially errno is %d */\n", errno);
printf("/* There are %d entries in sys_errlist[] */\n", sys_nerr);
printf("/* The 2nd sys_errlist entry is \"%s\" */\n\n", sys_errlist[1]);
printf("/*\n");
printf(" * Based on the above, calc_errno now knows\n");
printf(" * how to declare errno and friends.\n");
printf(" */\n\n");
printf("extern int errno;\t\t/* last system error */\n");
printf("extern char *sys_errlist[];\t"
"/* system error messages */\n");
printf("extern int sys_nerr;\t\t/* number of system errors*/\n");
#else /* assume defined(TRY_ERRNO_STD_DECL) */
extern int errno; /* last system error */
extern const char *const sys_errlist[]; /* system error messages */
extern int sys_nerr; /* number of system errors*/
printf("/*\n");
printf(" * The following comments were produced by calc_errno\n");
printf(" * in an effort to see if these values were correctly\n");
printf(" * declared when calc_errno.c was compiled.\n");
printf(" */\n\n");
printf("/* Initially errno is %d */\n", errno);
printf("/* There are %d entries in sys_errlist[] */\n", sys_nerr);
printf("/* The 2nd sys_errlist entry is \"%s\" */\n\n", sys_errlist[1]);
printf("/*\n");
printf(" * Based on the above, calc_errno now knows\n");
printf(" * how to declare errno and friends.\n");
printf(" */\n\n");
printf("extern int errno;\t\t\t/* last system error */\n");
printf("extern const char *const sys_errlist[];\t"
"/* system error messages */\n");
printf("extern int sys_nerr;\t\t\t/* number of system errors*/\n");
#endif
/* exit(0); */
return 0;
}

View File

@@ -336,3 +336,5 @@ E_STRCPY Bad argument type for strcpy
E_STRNCPY Bad argument type for strncpy
E_BACKSLASH Bad argument type for unary backslash
E_SETMINUS Bad argument type for setminus
E_INDICES1 Bad first argument type for indices
E_INDICES2 Bad second argument for indices

169
codegen.c
View File

@@ -32,8 +32,8 @@ static void getfunction(void);
static void ungetfunction(void);
static void getbody(LABEL *contlabel, LABEL *breaklabel,
LABEL *nextcaselabel, LABEL *defaultlabel);
static void getdeclarations(int symtype);
static void getsimpledeclaration (int symtype);
static int getdeclarations(int symtype);
static int getsimpledeclaration (int symtype);
static int getonevariable (int symtype);
static void getstatement(LABEL *contlabel, LABEL *breaklabel,
LABEL *nextcaselabel, LABEL *defaultlabel);
@@ -256,9 +256,15 @@ ungetfunction(void)
case T_MULT:
rmalluserfunc();
continue;
default:
case T_NEWLINE:
case T_SEMICOLON:
case T_EOF:
rescantoken();
return;
default:
scanerror(T_SEMICOLON,
"Non-name arg for undefine");
return;
}
}
}
@@ -398,9 +404,11 @@ getbody(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *defaul
* declarations = { LOCAL | GLOBAL | STATIC } onedeclaration
* [ ',' onedeclaration ] ... ';'.
*/
static void
static int
getdeclarations(int symtype)
{
int res = 0;
while (TRUE) {
switch (gettoken()) {
case T_COMMA:
@@ -411,28 +419,31 @@ getdeclarations(int symtype)
case T_RIGHTBRACE:
case T_EOF:
rescantoken();
return;
return res;
case T_SYMBOL:
addopone(OP_DEBUG, linenumber());
rescantoken();
getsimpledeclaration(symtype);
if (getsimpledeclaration(symtype))
res = 1;
break;
case T_MAT:
addopone(OP_DEBUG, linenumber());
getmatdeclaration(symtype);
res = 1;
break;
case T_OBJ:
addopone(OP_DEBUG, linenumber());
getobjdeclaration(symtype);
addop(OP_POP);
res = 1;
break;
default:
scanerror(T_SEMICOLON, "Bad syntax in declaration statement");
return;
return res;
}
}
}
@@ -444,22 +455,24 @@ getdeclarations(int symtype)
* Subsequences end with "," or at end of line; spaces indicate
* repeated assignment, e.g. "c d = 2" has the effect of "c = 2, d = 2".
*/
static void
static int
getsimpledeclaration(int symtype)
{
int res = 0;
for (;;) {
switch (gettoken()) {
case T_SYMBOL:
rescantoken();
if (getonevariable(symtype))
res = getonevariable(symtype);
if (res)
addop(OP_POP);
continue;
case T_COMMA:
continue;
default:
rescantoken();
return;
return res;
}
}
}
@@ -508,11 +521,9 @@ getonevariable(int symtype)
* | BREAK ';'
* | RETURN assignment ';'
* | GOTO label ';'
* | MAT name '[' value [ ':' value ] [',' value [ ':' value ] ] ']' ';'
* | OBJ type '{' arg [ ',' arg ] ... '}' ] ';'
* | OBJ type name [ ',' name ] ';'
* | PRINT assignment [, assignment ] ... ';'
* | QUIT [ string ] ';'
* | ABORT [ string ] ';'
* | SHOW item ';'
* | body
* | assignment ';'
@@ -541,18 +552,20 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d
return;
case T_GLOBAL:
getdeclarations(SYM_GLOBAL);
(void) getdeclarations(SYM_GLOBAL);
break;
case T_STATIC:
clearlabel(&label);
addoplabel(OP_INITSTATIC, &label);
getdeclarations(SYM_STATIC);
if (getdeclarations(SYM_STATIC))
setlabel(&label);
else
curfunc->f_opcodecount -= 2;
break;
case T_LOCAL:
getdeclarations(SYM_LOCAL);
(void) getdeclarations(SYM_LOCAL);
break;
case T_RIGHTBRACE:
@@ -692,14 +705,14 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d
}
}
if (gettoken() != T_RIGHTPAREN) { /* have 'c' part */
if (label1.l_offset <= 0)
if (label1.l_offset < 0)
addoplabel(OP_JUMP, &label3);
setlabel(&label2);
contlabel = &label2;
rescantoken();
(void) getexprlist();
addop(OP_POP);
if (label1.l_offset > 0)
if (label1.l_offset >= 0)
addoplabel(OP_JUMP, &label1);
if (gettoken() != T_RIGHTPAREN) {
(void) tokenmode(oldmode);
@@ -719,15 +732,21 @@ getstatement(LABEL *contlabel, LABEL *breaklabel, LABEL *nextcaselabel, LABEL *d
case T_WHILE:
oldmode = tokenmode(TM_DEFAULT);
contlabel = &label1;
breaklabel = &label2;
clearlabel(contlabel);
clearlabel(breaklabel);
setlabel(contlabel);
getcondition();
if (gettoken() != T_SEMICOLON) {
breaklabel = &label2;
clearlabel(breaklabel);
addoplabel(OP_JUMPZ, breaklabel);
getstatement(contlabel, breaklabel, NULL_LABEL, NULL_LABEL);
rescantoken();
getstatement(contlabel, breaklabel,
NULL_LABEL, NULL_LABEL);
addoplabel(OP_JUMP, contlabel);
setlabel(breaklabel);
} else {
addoplabel(OP_JUMPNZ, contlabel);
}
(void) tokenmode(oldmode);
return;
@@ -1038,18 +1057,14 @@ getoneobj(long index, int symtype)
}
/*
* Routine to collect a set of variables for the specified object type
* and initialize them as being that type of object.
* Here
* objlist = name initlist [ ',' name initlist ] ... ';'.
* If symtype is SYM_UNDEFINED, then this is an OBJ statement where the
* values can be any variable expression, and no symbols are to be defined.
* Otherwise this is part of a declaration, and the variables must be raw
* symbol names which are defined with the specified symbol type.
* Routine to assign a specified object-type value to each of a set of
* variables in a "global", "local" or "static" declaration, or, if
* symtype is SYM_UNDEFINED, to create one object value of the specified
* type.
*
* given:
* name object name
* symtype type of symbol to collect for
* symtype declaration type
*/
static void
getobjvars(char *name, int symtype)
@@ -1063,6 +1078,8 @@ getobjvars(char *name, int symtype)
}
for (;;) {
getoneobj(index, symtype);
if (symtype == SYM_UNDEFINED)
return;
if (gettoken() != T_COMMA) {
rescantoken();
return;
@@ -1118,6 +1135,21 @@ getonematrix(int symtype)
}
rescantoken();
if (gettoken() == T_LEFTPAREN) {
if (isrvalue(getexprlist())) {
scanerror(T_SEMICOLON, "Lvalue expected");
return;
}
if (gettoken() != T_RIGHTPAREN) {
scanerror(T_SEMICOLON, "Missing right parenthesis");
return;
}
getonematrix(symtype);
addop(OP_ASSIGN);
return;
}
rescantoken();
if (gettoken() != T_LEFTBRACKET) {
rescantoken();
scanerror(T_SEMICOLON, "Left-bracket expected");
@@ -1133,6 +1165,7 @@ getonematrix(int symtype)
* will patch the correct value back into the opcode.
*/
if (gettoken() == T_RIGHTBRACKET) {
if (gettoken() == T_ASSIGN) {
clearopt();
patchpc = curfunc->f_opcodecount + 1;
addopone(OP_NUMBER, (long) -1);
@@ -1142,16 +1175,24 @@ getonematrix(int symtype)
addop(OP_ZERO);
addop(OP_INITFILL);
count = 0;
if (gettoken() == T_ASSIGN)
count = getinitlist();
else
rescantoken();
index = addqconstant(itoq(count));
if (index < 0)
math_error("Cannot allocate constant");
curfunc->f_opcodes[patchpc] = index;
return;
}
rescantoken();
addopone(OP_MATCREATE, 0);
if (gettoken() == T_LEFTBRACKET) {
creatematrix();
} else {
rescantoken();
addop(OP_ZERO);
}
addop(OP_INITFILL);
return;
}
/*
* This isn't implicit, so we expect expressions for the bounds.
@@ -1169,26 +1210,10 @@ creatematrix(void)
{
long dim;
dim = 1;
dim = 0;
while (TRUE) {
(void) getopassignment();
switch (gettoken()) {
case T_RIGHTBRACKET:
case T_COMMA:
rescantoken();
addop(OP_ONE);
addop(OP_SUB);
addop(OP_ZERO);
break;
case T_COLON:
(void) getopassignment();
break;
default:
rescantoken();
}
switch (gettoken()) {
case T_RIGHTBRACKET:
for (;;) {
if (gettoken() == T_RIGHTBRACKET) {
addopone(OP_MATCREATE, dim);
if (gettoken() == T_LEFTBRACKET) {
creatematrix();
@@ -1198,12 +1223,32 @@ creatematrix(void)
}
addop(OP_INITFILL);
return;
case T_COMMA:
if (++dim <= MAXDIM)
break;
}
rescantoken();
if (++dim > MAXDIM) {
scanerror(T_SEMICOLON, "Only %ld dimensions allowed", MAXDIM);
return;
}
(void) getopassignment();
switch (gettoken()) {
case T_RIGHTBRACKET:
rescantoken();
case T_COMMA:
addop(OP_ONE);
addop(OP_SUB);
addop(OP_ZERO);
break;
case T_COLON:
(void) getopassignment();
switch(gettoken()) {
case T_RIGHTBRACKET:
rescantoken();
case T_COMMA:
continue;
}
/*FALLTHRU*/
default:
rescantoken();
scanerror(T_SEMICOLON, "Illegal matrix definition");
return;
}
@@ -1906,11 +1951,6 @@ getterm(void)
case T_MAT:
getonematrix(SYM_UNDEFINED);
while (gettoken() == T_COMMA) {
addop(OP_POP);
getonematrix(SYM_UNDEFINED);
}
rescantoken();
type = EXPR_ASSIGN;
break;
@@ -2179,8 +2219,14 @@ getmatargs(void)
* finds that the element will be referenced for writing, then
* it will call writeindexop to change the flag in the opcode.
*/
dim = 1;
dim = 0;
if (gettoken() == T_RIGHTBRACKET) {
addoptwo(OP_INDEXADDR, (long) dim, (long) FALSE);
return;
}
rescantoken();
for (;;) {
++dim;
(void) getopassignment();
switch (gettoken()) {
case T_RIGHTBRACKET:
@@ -2188,7 +2234,6 @@ getmatargs(void)
(long) FALSE);
return;
case T_COMMA:
dim++;
break;
default:
rescantoken();

View File

@@ -138,38 +138,6 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
up1 = up2 = 0;
sign = (R & 64) != 0;
#if 0
if (qiszero(epsilon)) {
aes = qsquare(c->real);
bes = qsquare(c->imag);
v = qqadd(aes, bes);
qfree(aes);
qfree(bes);
u = qsqrt(v, epsilon, 0);
qfree(v);
if (qiszero(u)) {
qfree(u);
return clink(&_czero_);
}
aes = qqadd(u, c->real);
qfree(u);
bes = qscale(aes, -1);
qfree(aes);
u = qsqrt(bes, epsilon, R);
qfree(bes);
if (qiszero(u)) {
qfree(u);
return clink(&_czero_);
}
aes = qscale(c->imag, -1);
v = qqdiv(aes, u);
qfree(aes);
r = comalloc();
r->real = u;
r->imag = v;
return r;
}
#endif
imsign = c->imag->num.sign;
es = qsquare(epsilon);
aes = qqdiv(c->real, es);
@@ -255,8 +223,7 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
up2 = -1;
zfree(tmp1);
zfree(aa);
}
else {
} else {
s1 = zsqrt(tmp3, &cc, 0);
zfree(tmp3);
zadd(cc, a, &tmp1);
@@ -333,9 +300,9 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
zfree(mul2);
mul2 = tmp2;
}
if (ziszero(mul1))
if (ziszero(mul1)) {
u = qlink(&_qzero_);
else {
} else {
mul1.sign = sign ^ epsilon->num.sign;
u = qalloc();
zreduce(mul1, epsilon->den, &tmp2, &u->den);
@@ -343,9 +310,9 @@ csqrt(COMPLEX *c, NUMBER *epsilon, long R)
zfree(tmp2);
}
zfree(mul1);
if (ziszero(mul2))
if (ziszero(mul2)) {
v = qlink(&_qzero_);
else {
} else {
mul2.sign = imsign ^ sign ^ epsilon->num.sign;
v = qalloc();
zreduce(mul2, epsilon->den, &tmp2, &v->den);
@@ -1147,5 +1114,3 @@ cprintfr(COMPLEX *c)
zprintval(i->den, 0L, 0L);
}
}
/* END CODE */

318
config.c
View File

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

View File

@@ -29,7 +29,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/
@@ -81,6 +81,7 @@
#define CONFIG_CALC_DEBUG 31
#define CONFIG_USER_DEBUG 32
#define CONFIG_VERBOSE_QUIT 33
#define CONFIG_CTRL_D 34
/*
@@ -102,7 +103,9 @@
*
* quickhash.c - config_hash()
* hash.c - hash_value()
* config.c - setconfig(), config_value(), config_cmp()
* config.c - configs[], oldstd, newstd, setconfig(),
* config_value(), config_cmp()
* config.h - CONFIG_XYZ_SYMBOL (see above)
*/
struct config {
int outmode; /* current output mode */
@@ -139,6 +142,7 @@ struct config {
long lib_debug; /* library debug, see LIB_DEBUG_XXX below */
long user_debug; /* user defined debug value: 0 default */
BOOL verbose_quit; /* TRUE => print Quit or abort executed msg */
int ctrl_d; /* see CTRL_D_xyz below */
};
typedef struct config CONFIG;
@@ -148,7 +152,8 @@ typedef struct config CONFIG;
*/
#define LIBDBG_STDIN_FUNC (0x00000001) /* interactive func define debug */
#define LIBDBG_FILE_FUNC (0x00000002) /* file read func define debug */
#define LIBDBG_MASK (0x00000003)
#define LIBDBG_FUNC_INFO (0x00000004) /* print extra info for show func */
#define LIBDBG_MASK (0x00000007)
/*
@@ -162,6 +167,13 @@ typedef struct config CONFIG;
#define CALCDBG_RUNSTATE (0x00000020) /* report run_state changes */
#define CALCDBG_MASK (0x0000003f)
/*
* ctrl-d meanings
*/
#define CTRL_D_VIRGIN (0) /* ^D only exits on virgin command lines */
#define CTRL_D_EMACS (1) /* ^D never exits, emacs binding meaning only */
#define CTRL_D_EOF (2) /* ^D always exits at start of line */
/*
* global configuration states and aliases

View File

@@ -25,7 +25,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -29,7 +29,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -19,7 +19,7 @@
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
#
# chongo was here /\../\ http://reality.sgi.com/chongo
# chongo was here /\../\ http://reality.sgi.com/chongo/
The following custom calc library files are provided because they serve
as examples of how use the custom interface. The custom interface

View File

@@ -27,7 +27,7 @@
# Happy bit twiddling,
#
# Landon Curt Noll
# http://reality.sgi.com/chongo
# http://reality.sgi.com/chongo/
#
# chongo <was here> /\../\
@@ -285,6 +285,10 @@ H_SRC= ${CUSTOM_H_SRC}
DISTLIST= ${CUSTCALC_SRC} ${CUSTOM_CALC_FILES} ${CUSTOM_HELP} \
${INSTALL_H_SRC} CUSTOM_CAL HOW_TO_ADD ${MAKE_FILE}
# These files are used to make (but not built) a calc .a library
#
CALCLIBLIST= ${CUSTCALC_SRC} ${INSTALL_H_SRC} ${MAKE_FILE} HOW_TO_ADD
# complete list of targets
#
TARGETS= libcustcalc.a ${CUSTCALC_OBJ}
@@ -310,6 +314,15 @@ libcustcalc.a: ${CUSTCALC_OBJ} ${MAKE_FILE} ../Makefile
ar qc libcustcalc.a ${CUSTCALC_OBJ}
${RANLIB} libcustcalc.a
##
#
# Special .o files
#
##
c_sysinfo.o: c_sysinfo.c ${MAKE_FILE}
${CC} ${CFLAGS} c_sysinfo.c -c
##
#
# used by the upper level Makefile
@@ -343,6 +356,13 @@ distlist: ${DISTLIST}
distdir:
${Q}echo custom
calcliblist: ${CALCLIBLIST}
${Q}for i in ${CALCLIBLIST} /dev/null; do \
if [ X"$$i" != X"/dev/null" ]; then \
echo custom/$$i; \
fi; \
done
##
#
# Home grown make dependency rules. Your system make not support
@@ -415,12 +435,12 @@ depend:
else \
rm -f Makefile.tmp; \
mv Makefile Makefile.tmp; \
if [ -d RCS ]; then; \
if [ -d RCS ]; then \
co -l Makefile; \
fi ;\
mv Makefile.tmp Makefile; \
if [ -d RCS ]; then; \
echo new custom Makefile formed '--' you need to check it in'; \
if [ -d RCS ]; then \
echo 'new custom Makefile formed -- you need to check it in'; \
fi; \
fi

View File

@@ -10,7 +10,7 @@
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* chongo was here /\../\ http://reality.sgi.com/chongo
* chongo was here /\../\ http://reality.sgi.com/chongo/
*/
/*
* argv - print information about various args

View File

@@ -16,7 +16,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -16,7 +16,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -16,7 +16,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -16,7 +16,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/
@@ -33,6 +33,7 @@
#include "../config.h"
#include "../calc.h"
#include "../longbits.h"
#define CHECK_L_FORMAT
#include "../longlong.h"
#include "../block.h"
#include "../calcerr.h"
@@ -306,17 +307,33 @@ static void
dump_name_value(void)
{
struct infoname *p; /* current infoname */
char *fmt; /* printf value format */
/* dump the entire table */
for (p = sys_info; p->name != NULL; ++p) {
if (p->str == NULL) {
#if LONG_BITS == FULL_BITS || FULL_BITS == 32 || !defined(HAVE_LONGLONG)
printf("%s%-23s\t%-8lu\t(0x%lx)\n",
fmt = "%s%-23s\t%-8lu\t(0x%lx)\n";
printf(fmt,
(conf->tab_ok ? "\t" : ""), p->name,
(unsigned long)p->nmbr,
(unsigned long)p->nmbr);
#else
printf("%s%-23s\t%-8llu\t(0x%llx)\n",
/*
* Determine of %ld can print a 64 bit long long.
*
* Some systems that can make use of %ld to print a
* a 64 bit value do not support the %lld type.
* So we will only try %lld if %ld does not work.
*/
if (l_format < 0) {
/* %ld prints lower 32 bits only, use %lld */
fmt = "%s%-23s\t%-8llu\t(0x%llx)\n";
} else {
/* %ld prints all 64 bits, use %ld */
fmt = "%s%-23s\t%-8lu\t(0x%lx)\n";
}
printf(fmt,
(conf->tab_ok ? "\t" : ""), p->name,
(unsigned long long)p->nmbr,
(unsigned long long)p->nmbr);
@@ -337,17 +354,33 @@ static void
dump_mening_value(void)
{
struct infoname *p; /* current infoname */
char *fmt; /* printf value format */
/* dump the entire table */
for (p = sys_info; p->name != NULL; ++p) {
if (p->str == NULL) {
#if LONG_BITS == FULL_BITS || FULL_BITS == 32 || !defined(HAVE_LONGLONG)
printf("%s%-36.36s\t%-8lu\t(0x%lx)\n",
fmt = "%s%-36.36s\t%-8lu\t(0x%lx)\n";
printf(fmt,
(conf->tab_ok ? "\t" : ""), p->meaning,
(unsigned long)p->nmbr,
(unsigned long)p->nmbr);
#else
printf("%s%-36.36s\t%-8llu\t(0x%llx)\n",
/*
* Determine of %ld can print a 64 bit long long.
*
* Some systems that can make use of %ld to print a
* a 64 bit value do not support the %lld type.
* So we will only try %lld if %ld does not work.
*/
if (l_format < 0) {
/* %ld prints lower 32 bits only, use %lld */
fmt = "%s%-36.36s\t%-8llu\t(0x%llx)\n";
} else {
/* %ld prints all 64 bits, use %ld */
fmt = "%s%-36.36s\t%-8lu\t(0x%lx)\n";
}
printf(fmt,
(conf->tab_ok ? "\t" : ""), p->meaning,
(unsigned long long)p->nmbr,
(unsigned long long)p->nmbr);

View File

@@ -25,7 +25,7 @@
* Happy bit twiddling,
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -10,7 +10,7 @@
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* chongo was here /\../\ http://reality.sgi.com/chongo
* chongo was here /\../\ http://reality.sgi.com/chongo/
*/
/*
* halflen - determine the length of numeric value in HALFs

9
file.c
View File

@@ -2228,15 +2228,16 @@ freadnum(FILE *fp, VALUE *valptr)
ch = fgetc(fp);
}
}
if (ch == 'i' || ch == 'I')
if (ch == 'i' || ch == 'I') {
imag = TRUE;
else {
} else {
ungetc(ch, fp);
}
if (ziszero(num)) {
zfree(num);
val.v_type = V_NUM;
val.v_subtype = V_NOSUBTYPE;
val.v_num = qlink(&_qzero_);
*valptr = val;
return;
@@ -2281,11 +2282,11 @@ freadnum(FILE *fp, VALUE *valptr)
c->imag = q;
val.v_type = V_COM;
val.v_com = c;
}
else {
} else {
val.v_type = V_NUM;
val.v_num = q;
}
val.v_subtype = V_NOSUBTYPE;
*valptr = val;
}

774
func.c

File diff suppressed because it is too large Load Diff

72
hash.c
View File

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

62
have_rusage.c Normal file
View File

@@ -0,0 +1,62 @@
/*
* have_rusage - Determine if we getrusage()
*
* usage:
* have_rusage
*
* Not all systems have the getrusage() function, so this may not
* compile on your system.
*
* This prog outputs several defines:
*
* HAVE_GETRUSAGE
* defined ==> use getrusage()
* undefined ==> do not call or cannot call getrusage()
*/
/*
* Copyright (c) 1999 by Landon Curt Noll. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright, this permission notice and text
* this comment, and the disclaimer below appear in all of the following:
*
* supporting documentation
* source copies
* source works derived from this source
* binaries derived from this source or from derived source
*
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* chongo was here /\../\
*/
#include <sys/time.h>
#include <sys/resource.h>
int
main(void)
{
#if defined(HAVE_NO_GETRUSAGE)
printf("#undef HAVE_GETRUSAGE /* no */\n");
#else /* HAVE_NO_GETRUSAGE */
struct rusage rusage; /* resource utilization */
(void) getrusage(RUSAGE_SELF, &rusage);
printf("#define HAVE_GETRUSAGE /* yes */\n");
#endif /* HAVE_NO_GETRUSAGE */
/* exit(0); */
return 0;
}

62
have_strdup.c Normal file
View File

@@ -0,0 +1,62 @@
/*
* have_strdup - Determine if we strdup()
*
* usage:
* have_strdup
*
* Not all systems have the strdup() function, so this may not
* compile on your system.
*
* This prog outputs several defines:
*
* HAVE_STRDUP
* defined ==> use strdup()
* undefined ==> do not call or cannot call strdup()
*/
/*
* Copyright (c) 1999 by Landon Curt Noll. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright, this permission notice and text
* this comment, and the disclaimer below appear in all of the following:
*
* supporting documentation
* source copies
* source works derived from this source
* binaries derived from this source or from derived source
*
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* chongo was here /\../\
*/
#include <string.h>
int
main(void)
{
#if defined(HAVE_NO_STRDUP)
printf("#undef HAVE_STRDUP /* no */\n");
#else /* HAVE_NO_STRDUP */
char *p;
p = strdup("#define HAVE_STRDUP /* yes */");
if (p != NULL) {
printf("%s\n", p);
}
#endif /* HAVE_NO_STRDUP */
/* exit(0); */
return 0;
}

View File

@@ -35,13 +35,12 @@ Q=@
# standard tools
#
NATIVE_CC= cc
NATIVE_CFLAGS=
LCC= cc
ICFLAGS=
ILDFLAGS=
SED= sed
SORT= sort
FMT= fmt
CMP= cmp
CAT= cat
# Standard and Builtin help files
#
@@ -68,7 +67,7 @@ BLT_HELP_FILES_9= stdlib
STD_HELP_FILES_10= types usage unexpected variable
BLT_HELP_FILES_11= altbind bindings custom_cal libcalc new_custom stdlib
BLT_HELP_FILES_11= bindings custom_cal libcalc new_custom stdlib
STD_HELP_FILES_12= archive
@@ -105,16 +104,16 @@ BLT_HELP_FILES= ${BLT_HELP_FILES_3} ${BLT_HELP_FILES_5} \
# This list is prodiced by the detaillist rule when no WARNINGS are detected.
#
DETAIL_HELP= abs access acos acosh acot acoth acsc acsch address agd append \
appr arg arrow asec asech asin asinh assign atan atan2 atanh avg \
base bit blk blkcpy blkfree blocks bround btrunc calclevel ceil \
cfappr cfsim char cmdbuf cmp comb conj cos cosh cot coth count cp \
csc csch ctime delete den dereference det digit digits dp epsilon \
errcount errmax errno error eval exp fact factor fclose fcnt feof \
ferror fflush fgetc fgetfield fgetline fgets fgetstr fib files \
floor fopen forall fprintf fputc fputs fputstr frac free freeglobals \
freeredc freestatics frem freopen fscan fscanf fseek fsize ftell gcd \
gcdrem gd getenv hash head highbit hmean hnrmod hypot ilog ilog10 \
ilog2 im inputlevel insert int inverse iroot isassoc isatty isblk \
appr arg arrow asec asech asin asinh assign atan atan2 atanh avg base \
bit blk blkcpy blkfree blocks bround btrunc calclevel ceil cfappr \
cfsim char cmdbuf cmp comb conj cos cosh cot coth count cp csc csch \
ctime delete den dereference det digit digits dp epsilon errcount \
errmax errno error eval exp fact factor fclose fcnt feof ferror \
fflush fgetc fgetfield fgetline fgets fgetstr fib files floor fopen \
forall fprintf fputc fputs fputstr frac free freeglobals freeredc \
freestatics frem freopen fscan fscanf fseek fsize ftell gcd gcdrem \
gd getenv hash head highbit hmean hnrmod hypot ilog ilog10 ilog2 \
im indices inputlevel insert int inverse iroot isassoc isatty isblk \
isconfig isdefined iserror iseven isfile ishash isident isint islist \
ismat ismult isnull isnum isobj isobjtype isodd isprime isptr isqrt \
isrand israndom isreal isrel issimple issq isstr istype jacobi join \
@@ -148,6 +147,10 @@ DISTLIST= ${STD_HELP_FILES} ${DETAIL_HELP} ${MAKE_FILE} \
obj.file builtin.top builtin.end funclist.sed \
errorcodes.hdr errorcodes.sed
# These files are used to make (but not built) a calc .a library
#
CALCLIBLIST=
all: ${FULL_HELP_FILES} full ${DETAIL_HELP} ${DETAIL_CLONE} \
${SINGULAR_FILES} calc .all
@@ -172,18 +175,6 @@ bindings: ../lib/bindings
true; \
fi
altbind: ../lib/altbind
rm -f $@
cp ../lib/altbind $@
chmod 0444 $@
-@if [ -z "${Q}" ]; then \
echo ''; \
echo '=-=-= skipping the cat of help/$@ =-=-='; \
echo ''; \
else \
true; \
fi
stdlib: ../lib/README
rm -f $@
cp ../lib/README $@
@@ -234,7 +225,7 @@ bugs: ../BUGS
errorcodes: ../calcerr.h errorcodes.hdr errorcodes.sed
rm -f $@
${CAT} errorcodes.hdr > $@
cat errorcodes.hdr > $@
${SED} -n -f errorcodes.sed < ../calcerr.h >> $@
chmod 0444 $@
-@if [ -z "${Q}" ]; then \
@@ -359,17 +350,13 @@ ${SINGULAR_FILES}: ${PLURAL_FILES}
#
builtin: builtin.top builtin.end ../func.c funclist.sed
${Q}echo "forming builtin help file"
-${Q}rm -f builtin
${Q}cat builtin.top > builtin
-${Q}rm -f funclist.c
${Q}${SED} -n -f funclist.sed ../func.c > funclist.c
-${Q}rm -f ../funclist.c ../funclist.o ../funclist funclist
${Q}cp funclist.c ..
-${Q}(cd ..; \
${NATIVE_CC} ${NATIVE_CFLAGS} -DFUNCLIST funclist.c -o funclist; \
mv funclist help; \
rm -f funclist.c funclist.o funclist)
-${Q}rm -f funclist.o funclist
${Q}${LCC} ${ICFLAGS} -DFUNCLIST -I/usr/include -I.. funclist.c -c
${Q}${LCC} ${ILDFLAGS} funclist.o -o funclist
-${Q}rm -f builtin
${Q}cat builtin.top > builtin
${Q}./funclist | \
${SED} -e 's/^/ /' -e 's/[ ][ ]*$$//' >> builtin
${Q}cat builtin.end >> builtin
@@ -400,6 +387,13 @@ distlist: ${DISTLIST}
distdir:
${Q}echo help
calcliblist:
${Q}for i in ${CALCLIBLIST} /dev/null; do \
if [ X"$$i" != X"/dev/null" ]; then \
echo help/$$i; \
fi; \
done
# The BSDI cdrom makefile expects all help files to be pre-built. This rule
# creats these fils so that the release can be shipped off to BSDI. You can
# ignore this rule.

View File

@@ -11,6 +11,6 @@ Where to get the the latest versions of calc
for information on how to obtain up a recent version of calc.
Landon Curt Noll
http://reality.sgi.com/chongo
http://reality.sgi.com/chongo/
chongo <was here> /\../\

View File

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

View File

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

View File

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

View File

@@ -36,17 +36,33 @@ gziped (or compressed) tar file).
You should send submissions to:
calc-tester@postofc.corp.sgi.com
calc-tester at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
Thanks for considering submitting code to calc. Calc is a collective
work by a number of people. It would not be what it is today without
your efforts and submissions!
Calc bug reports, however, should be sent to:
calc-bugs at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
See the BUGS file or try the help command:
help bugs
for details on bug reporting.
=-=
One may join the calc testing group by sending a request to:
calc-tester-request@postofc.corp.sgi.com
calc-tester-request at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
Your message body (not the subject) should consist of:
@@ -58,6 +74,6 @@ One may join the calc testing group by sending a request to:
is your full name.
Landon Curt Noll
http://reality.sgi.com/chongo
http://reality.sgi.com/chongo/
chongo <was here> /\../\

View File

@@ -2,7 +2,11 @@ Credits
The majority of calc was written by David I. Bell.
Calc archives and calc-tester mailing list maintained by Landon Curt Noll.
The Calc primary mirror, calc mailing list and calc bug report
processing is performed by Landon Curt Noll.
Landon Curt Noll maintains the master reference source, performs
release control functions as well as other calc maintenance functions.
Thanks for suggestions and encouragement from Peter Miller,
Neil Justusson, and Landon Noll.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,5 @@ s/NUMBER[ ]*\*/int /
s/NUMBER/int/
s/STRINGHEAD/int/
s/\(".*",.*,.*\),.*,.*,.*,.*,/\1, 0, 0, 0, 0,/
/sed me out/d
s/showbuiltins/main/
s/[ ][ ]*$//
p

View File

@@ -15,12 +15,12 @@ DESCRIPTION
The basis of this hash algorithm was taken from an idea sent
as reviewer comments to the IEEE POSIX P1003.2 committee by:
Phong Vo (http://www.research.att.com/info/kpv)
Phong Vo (http://www.research.att.com/info/kpv/)
Glenn Fowler (http://www.research.att.com/~gsf/)
In a subsequent ballot round:
Landon Curt Noll (http://reality.sgi.com/chongo)
Landon Curt Noll (http://reality.sgi.com/chongo/)
improved on their algorithm. Some people tried this hash
and found that it worked rather well. In an EMail message

View File

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

58
help/indices Normal file
View File

@@ -0,0 +1,58 @@
NAME
indices - indices for specified matrix or association element
SYNOPSIS
indices(V, index)
TYPES
V matrix or association
index integer
return list with up to 4 elements
DESCRIPTION
For 0 <= index < size(V), indices(V, index) returns list(i_0, i_1, ...)
for which V[i_0, i_1, ...] is the same lvalue as V[[index]].
For other values of index, a null value is returned.
This function can be useful for determining those elements for which
the indices satisfy some condition. This is particularly so for
associations since these have no simple relation between the
double-bracket index and the single-bracket indices, which may be
non-integer numbers or strings or other types of value. The
information provided by indices() is often required after the use
of search() or rsearch() which, when successful, return the
double-bracket index of the item found.
EXAMPLE
> mat M[2,3,1:5]
> indices(M, 11)
list (3 elements, 2 nonzero):
[[0]] = 0
[[1]] = 2
[[2]] = 2
> A = assoc();
> A["cat", "dog"] = "fight";
> A[2,3,5,7] = "primes";
> A["square", 3] = 9
> indices(A, search(A, "primes"))
list (4 elements, 4 nonzero):
[[0]] = 2
[[1]] = 3
[[2]] = 5
[[3]] = 7
LIMITS
abs(index) < 2^31
LIBRARY
LIST* associndices(ASSOC *ap, long index)
LIST* matindices(MATRIX *mp, long index)
SEE ALSO
assoc, mat

457
help/mat
View File

@@ -1,102 +1,397 @@
Using matrices
NAME
mat - keyword to create a matrix value
Matrices can have from 1 to 4 dimensions, and are indexed by a
normal-sized integer. The lower and upper bounds of a matrix can
be specified at runtime. The elements of a matrix are defaulted
to zeroes, but can be assigned to be of any type. Thus matrices
can hold complex numbers, strings, objects, etc. Matrices are
stored in memory as an array so that random access to the elements
is easy.
SYNOPSIS
mat [index-range-list] [ = {value_0. ...} ]
mat [] [= {value_0, ...}]
mat variable_1 ... [index-range-list] [ = {value_0, ...} ]
mat variable_1 ... [] [ = {value_0, ...} ]
Matrices are normally indexed using square brackets. If the matrix
is multi-dimensional, then an element can be indexed either by
using multiple pairs of square brackets (as in C), or else by
separating the indexes by commas. Thus the following two statements
reference the same matrix element:
mat [index-range-list_1[index-ranges-list_2] ... [ = { { ...} ...} ]
x = name[3][5];
x = name[3,5];
decl id_1 id_2 ... [index-range-list] ...
The double-square bracket operator can be used on any matrix to
make references to the elements easy and efficient. This operator
bypasses the normal indexing mechanism, and treats the array as if
it was one-dimensional and with a lower bound of zero. In this
indexing mode, elements correspond to the normal indexing mode where
the rightmost index increases most frequently. For example, when
using double-square bracket indexing on a two-dimensional matrix,
increasing indexes will reference the matrix elements left to right,
row by row. Thus in the following example, 'x' and 'y' are copied
from the same matrix element:
TYPES
index-range-list range_1 [, range_2, ...] up to 4 ranges
range_1, ... integer, or integer_1 : integer_2
value, value_1, ... any
variable_1 ... lvalue
decl declarator = global, static or local
id_1, ... identifier
mat m[1:2, 1:3];
x = m[2,1];
y = m[[3]];
DESCRIPTION
The expression mat [index-range-list] returns a matrix value.
This may be assigned to one or more lvalues A, B, ... by either
There are functions which return information about a matrix.
The 'size' functions returns the total number of elements.
The 'matdim', 'matmin', and 'matmax' functions return the number
of dimensions of a matrix, and the lower and upper index bounds
for a dimension of a matrix. For square matrices, the 'det'
function calculates the determinant of the matrix.
mat A B ... [index-range-list]
Some functions return matrices as their results. These functions
do not affect the original matrix argument, but instead return
new matrices. For example, the 'mattrans' function returns the
transpose of a matrix, and 'inverse' returns the inverse of a
matrix. So to invert a matrix called 'x', you could use:
or
x = inverse(x);
A = B = ... = mat[index-range-list]
The 'matfill' function fills all elements of a matrix with the
specified value, and optionally fills the diagonal elements of a
square matrix with a different value. For example:
If a variable is specified by an expression that is not a symbol with
possibly object element specifiers, the expression should be enclosed
in parentheses. For example, parentheses are required in
mat (A[2]) [3] and mat (*p) [3] but mat P.x [3] is acceptable.
matfill(x,1);
When an index-range is specified as integer_1 : integer_2, where
integer_1 and integer_2 are expressions which evaluate to integers,
the index-range consists of all integers from the minimum of the
two integers to the maximum of the two integers. For example,
mat[2:5, 0:4] and mat[5:2, 4:0] return the same matrix value.
will fill any matrix with ones, and:
If an index-range is an expression which evaluates to an integer,
the range is as if specified by 0 : integer - 1. For example,
mat[4] and mat[0:3] return the same 4-element matrix; mat[-2] and
mat[-3:0] return the same 4-element matrix.
matfill(x, 0, 1);
If the variable A has a matrix value, then for integer indices
i_1, i_2, ..., equal in number to the number of ranges specified at
its creation, and such that each index is in the corresponding range,
the matrix element associated with those index list is given as an
lvalue by the expressions A[i_1, i_2, ...].
will create an identity matrix out of any square matrix. Note that
unlike most matrix functions, this function does not return a matrix
value, but manipulates the matrix argument itself.
The elements of the matrix are stored internally as a linear array
in which locations are arranged in order of increasing indices.
For example, in order of location, the six element of A = mat [2,3]
are
Matrices can be multiplied by numbers, which multiplies each element
by the number. Matrices can also be negated, conjugated, shifted,
rounded, truncated, fractioned, and modulo'ed. Each of these
operations is applied to each element.
A[0,0], A[0,1], A[0,2], A[1,0], A[1,,1], A[1,2].
Matrices can be added or multiplied together if the operation is
legal. Note that even if the dimensions of matrices are compatible,
operations can still fail because of mismatched lower bounds. The
lower bounds of two matrices must either match, or else one of them
must have a lower bound of zero. Thus the following code:
These elements may also be specified using the double-bracket operator
with a single integer index as in A[[0]], A[[1]], ..., A[[5]].
If p is assigned the value &A[0.0], the address of A[[i]] for 0 <= i < 6
is p + i as long as A exists and a new value is not assigned to A.
mat x[3:3];
mat y[4:4];
z = x + y;
When a matrix is created, each element is initially assigned the
value zero. Other values may be assigned then or later using the
"= {...}" assignment operation. Thus
fails because the calculator does not have a way of knowing what
the bounds should be on the resulting matrix. If the bounds match,
then the resulting matrix has the same bounds. If exactly one of
the lower bounds is zero, then the resulting matrix will have the
nonzero lower bounds. Thus means that the bounds of a matrix are
preserved when operated on by matrices with lower bounds of zero.
For example:
A = {value_0, value_1, ...}
mat x[3:7];
mat y[5];
z = x + y;
assigns the values value_0, value_1, ... to the elements A[[0]],
A[[1]], ... Any blank "value" is passed over. For example,
will succeed and assign the variable 'z' a matrix whose
bounds are 3-7.
A = {1, , 2}
Vectors are matrices of only a single dimension. The 'dp' and 'cp'
functions calculate the dot product and cross product of a vector
(cross product is only defined for vectors of size 3).
will assign the value 1 to A[[0]], 2 to A[[2]] and leave all other
elements unchanged. Values may also be assigned to elements by
simple assignments, as in A[0,0] = 1, A[0,2] = 2;
Matrices can be searched for particular values by using the 'search'
and 'rsearch' functions. They return the element number of the
found value (zero based), or null if the value does not exist in the
matrix. Using the element number in double-bracket indexing will
then refer to the found element.
If the index-range is left blank but an initializer list is specified
as in
mat A[] = {1, 2 }
B = mat[] = {1, , 3, }
the matrix created is one-dimensional. If the list contains a
positive number n of values or blanks, the result is as if the
range were specified by [n], i.e. the range of indices is from
0 to n - 1. In the above examples, A is of size 2 with A[0] = 1
and A[1] = 2; B is of size 4 with B[0] = 1, B[1] = B[3] = 0,
B[2] = 3. The specification mat[] = { } creates the same as mat[1].
If the index-range is left blank and no initializer list is specified,
as in mat C[] or C = mat[], the matrix assigned to C has zero
dimension; this has one element C[]. To assign a value using "= { ...}"
at the same time as creating C, parentheses are required as in
(mat[]) = {value} or (mat C[]) = {value}. Later a value may be
assigned to C[] by C[] = value or C = {value}.
The value assigned at any time to any element of a matrix can be of
any type - number, string, list, matrix, object of previously specified
type, etc. For some matrix operations there are of course conditions
that elements may have to satisfy: for example, addition of matrices
requires that addition of corresponding elements be possible.
If an element of a matrix is a structure for which indices or an
object element specifier is required, an element of that structure is
referred to by appropriate uses of [ ] or ., and so on if an element
of that element is required. For example, one may have an expressions
like
A[1,2][3].alpha[2];
if A[1,2][3].alpha is a list with at least three elements, A[1,2][3] is
an object of a type like obj {alpha, beta}, A[1,2] is a matrix of
type mat[4] and A is a mat[2,3] matrix. When an element of a matrix
is a matrix and the total number of indices does not exceed 4, the
indices can be combined into one list, e.g. the A[1,2][3] in the
above example can be shortened to A[1,2,3]. (Unlike C, A[1,2] cannot
be expressed as A[1][2].)
The function ismat(V) returns 1 if V is a matrix, 0 otherwise.
isident(V) returns 1 if V is a square matrix with diagonal elements 1,
off-diagonal elements zero, or a zero- or one-dimensional matrix with
every element 1; otherwise zero is returned. Thus isident(V) = 1
indicates that for V * A and A * V where A is any matrix of
for which either product is defined and the elements of A are real
or complex numbers, that product will equal A.
If V is matrix-valued, test(V) returns 0 if every element of V tests
as zero; otherwise 1 is returned.
The dimension of a matrix A, i.e. the number of index-ranges in the
initial creation of the matrix, is returned by the function matdim(A).
For 1 <= i <= matdim(A), the minimum and maximum values for the i-th
index range are returned by matmin(A, i) and matmax(A,i), respectively.
The total number of elements in the matrix is returned by size(A).
The sum of the elements in the matrix is returned by matsum(A).
The default method of printing matrices is to give a line of information
about the matrix, and to list on separate lines up to 15 elements,
the indices and either the value (for numbers, strings, objects) or
some descriptive information for lists or matrices, etc.
Numbers are displayed in the current number-printing mode.
The maximum number of elements to be printed can be assigned
any nonnegative integer value m by config("maxprint", m).
Users may define another method of printing matrices by defining a
function mat_print(M); for example, for a not too big 2-dimensional
matrix A it is a common practice to use a loop like:
for (i = matmin(A,1); i <= matmax(A,1); i++) {
for (j = matmin(A,2); j <= matmax(A,2); j++)
printf("%8d", A[i,j];
print;
}
The default printing may be restored by
undefine mat_print;
The keyword "mat" followed by two or more index-range-lists returns a
matrix with indices specified by the first list, whose elements are
matrices as determined by the later index-range-lists. For
example mat[2][3] is a 2-element matrix, each of whose elements has
as its value a 3-element matrix. Values may be assigned to the
elements of the innermost matrices by nested = {...} operations as in
mat [2][3] = {{1,2,3},{4,5,6}}
An example of the use of mat with a declarator is
global mat A B [2,3], C [4]
This creates, if they do not already exist, three global variables with
names A, B, C, and assigns to A and B the value mat[2,3] and to C mat[4].
Some operations are defined for matrices.
A == B
Returns 1 if A and B are of the same "shape" and "corresponding"
elements are equal; otherwise 0 is returned. Being of the same
shape means they have the same dimension d, and for each i <= d,
matmax(A,i) - matmin(A,i) == matmax(B,i) - matmin(B,i),
One consequence of being the same shape is that the matrices will
have the same size. Elements "correspond" if they have the same
double-bracket indices; thus A == B implies that A[[i]] == B[[i]]
for 0 <= i < size(A) == size(B).
A + B
A - B
These are defined A and B have the same shape, the element
with double-bracket index j being evaluated by A[[j]] + B[[j]] and
A[[j]] - B[[j]], respectively. The index-ranges for the results
are those for the matrix A.
A[i,j]
If A is two-dimensional, it is customary to speak of the indices
i, j in A[i,j] as referring to rows and columns; the number of
rows is matmax(A,1) - matmin(A,1) + 1; the number of columns if
matmax(A,2) - matmin(A,2) + 1. A matrix is said to be square
if it is two-dimensional and the number of rows is equal to the
number of columns.
A * B
Multiplication is defined provided certain conditions by the
dimensions and shapes of A and B are satisfied. If both have
dimension 2 and the column-index-list for A is the same as
the row-index-list for B, C = A * B is defined in the usual
way so that for i in the row-index-list of A and j in the
column-index-list for B,
C[i,j] = Sum A[i,k] * B[k,j]
the sum being over k in the column-index-list of A. The same
formula is used so long as the number of columns in A is the same
as the number of rows in B and k is taken to refer to the offset
from matmin(A,2) and matmin(B,1), respectively, for A and B.
If the multiplications and additions required cannot be performed,
an execution error may occur or the result for C may contain
one or more error-values as elements.
If A or B has dimension zero, the result for A * B is simply
that of multiplying the elements of the other matrix on the
left by A[] or on the right by B[].
If both A and B have dimension 1, A * B is defined if A and B
have the same size; the result has the same index-list as A
and each element is the product of corresponding elements of
A and B. If A and B have the same index-list, this multiplication
is consistent with multiplication of 2D matrices if A and B are
taken to represent 2D matrices for which the off-diagonal elements
are zero and the diagonal elements are those of A and B.
the real and complex numbers.
If A is of dimension 1 and B is of dimension 2, A * B is defined
if the number of rows in B is the same as the size of A. The
result has the same index-lists as B; each row of B is multiplied
on the left by the corresponding element of A.
If A is of dimension 2 and B is of dimension 1, A * B is defined
if number of columns in A is the same as the size of A. The
result has the same index-lists as A; each column of A is
multiplied on the right by the corresponding element of B.
The algebra of additions and multiplications involving both one-
and two-dimensional matrices is particularly simple when all the
elements are real or complex numbers and all the index-lists are
the same, as occurs, for example, if for some positive integer n,
all the matrices start as mat [n] or mat [n,n].
det(A)
If A is a square, det(A) is evaluated by an algorithm that returns
the determinant of A if the elements of A are real or complex
numbers, and if such an A is non-singular, inverse(A) returns
the inverse of A indexed in the same way as A. For matrix A of
dimension 0 or 1, det(A) is defined as the product of the elements
of A in the order in which they occur in A, inverse(A) returns
a matrix indexed in the same way as A with each element inverted.
The following functions are defined to return matrices with the same
index-ranges as A and the specified operations performed on all
elements of A. Here num is an arbitrary complex number (nonzero
when it is a divisor), int an integer, rnd a rounding-type
specifier integer, real a real number.
num * A
A * num
A / num
- A
conj(A)
A << int, A >> int
scale(A, int)
round(A, int, rnd)
bround(A, int, rnd)
appr(A, real, rnd)
int(A)
frac(A)
A // real
A % real
A ^ int
If A and B are one-dimensional of the same size dp(A, B) returns
their dot-product, i.e. the sum of the products of corresponding
elements.
If A and B are one-dimension and of size 3, cp(A, B) returns their
cross-product.
randperm(A) returns a matrix indexed the same as A in which the elements
of A have been randomly permuted.
sort(A) returns a matrix indexed the same as A in which the elements
of A have been sorted.
If A is an lvalue whose current value is a matrix, matfill(A, v)
assigns the value v to every element of A, and if also, A is
square, matfill(A, v1, v2) assigns v1 to the off-diagonal elements,
v2 to the diagonal elements. To create and assign to A the unit
n * n matrix, one may use matfill(mat A[n,n], 0, 1).
For a square matrix A, mattrace(A) returns the trace of A, i.e. the
sum of the diagonal elements. For zero- or one-dimensional A,
mattrace(A) returns the sum of the elements of A.
For a two-dimensional matrix A, mattrans(A) returns the transpose
of A, i.e. if A is mat[m,n], it returns a mat[n,m] matrix with
[i,j] element equal to A[j,i]. For zero- or one-dimensional A,
mattrace(A) returns a matrix with the same value as A.
The functions search(A, value, start, end]) and
rsearch(A, value, start, end]) return the first or last index i
for which A[[i]] == value and start <= i < end, or if there is
no such index, the null value. For further information on default
values and the use of an "accept" function, see the help files for
search and rsearch.
reverse(A) returns a matrix with the same index-lists as A but the
elements in reversed order.
The copy and blkcpy functions may be used to copy data to a matrix from
a matrix or list, or from a matrix to a list. In copying from a
matrix to a matrix the matrices need not have the same dimension;
in effect they are treated as linear arrays.
EXAMPLE
> obj point {x,y}
> mat A[5] = {1, 2+3i, "ab", mat[2] = {4,5}. obj point = {6,7}}
> A
mat [5] (5 elements, 5 nonzero):
[0] = 1
[1] = 2+3i
[2] = "ab"
[3] = mat [2] (2 elements, 2 nonzero)
[4] = obj point {6, 7}
> print A[0], A[1], A[2], A[3][0], A[4].x
1 2+3i ab 4 6
> define point_add(a,b) = obj point = {a.x + b.x, a.y + b.y}
point_add(a,b) defined
> mat [B] = {8, , "cd", mat[2] = {9,10}, obj point = {11,12}}
> A + B
mat [5] (5 elements, 5 nonzero):
[0] = 9
[1] = 2+3i
[2] = "abcd"
[3] = mat [2] (2 elements, 2 nonzero)
[4] = obj point {17, 19}
> mat C[2,2] = {1,2,3,4}
> C^10
mat [2,2] (4 elements, 4 nonzero):
[0,0] = 4783807
[0,1] = 6972050
[1,0] = 10458075
[1,1] = 15241882
> C^-10
mat [2,2] (4 elements, 4 nonzero):
[0,0] = 14884.650390625
[0,1] = -6808.642578125
[1,0] = -10212.9638671875
[1,1] = 4671.6865234375
> mat A[4] = {1,2,3,4}, A * reverse(A);
mat [4] (4 elements, 4 nonzero):
[0] = 4
[1] = 6
[2] = 6
[3] = 4
LIMITS
The theoretical upper bound for the absolute values of indices is
2^31 - 1, but the size of matrices that can be handled in practice will
be limited by the availability of memory and what is an acceptable
runtime. For example, although it may take only a fraction of a
second to invert a 10 * 10 matrix, it will probably take about 1000
times as long to invert a 100 * 100 matrix.
LIBRARY
n/a
SEE ALSO
ismat, matdim, matmax, matmin, mattrans, mattrace, matsum, det, inverse,
isident, test, config, search, rsearch, reverse, copy, blkcpy, dp, cp,
randperm, sort

View File

@@ -19,9 +19,9 @@ DESCRIPTION
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:
applications, lavarand should be used. See the URL:
http://lavarand.sgi.com
http://lavarand.sgi.com/index.html
for information about seeding a pseudo-random number generator
(such as rand() or random()) with the cryptographic hash of the

View File

@@ -222,8 +222,7 @@ DESCRIPTION
The pre-defined Blum moduli and quadratic residues were selected
by lavarand, a hardware random number generator. See the URL:
http://lavarand.sgi.com
XXX - This URL is not available on 17Feb97 ... but will be soon.
http://lavarand.sgi.com/index.html
for an explanation of how the lavarand random number generator works.
For more information, see the comments at the top of the calc

View File

@@ -5,10 +5,22 @@ Calc Todo Items:
Code contributions are welcome. Send patches to:
calc-tester@postofc.corp.sgi.com
calc-tester at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
See also the 'wishlist' help files for the calc enhancement wish list.
Calc bug reports, however, should send to:
calc-tester at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
see the BUGS file or try the calc command:
help bugs
=-=
Very High priority items:
@@ -27,7 +39,6 @@ Very High priority items:
overview overview of calc
assoc using associations
command top level commands
config configuration parameters
define how to define functions
environment how environment variables effect calc
errorcodes calc generated error codes
@@ -36,7 +47,6 @@ Very High priority items:
history command history
interrupt how interrupts are handled
list using lists
mat using matrices
obj user defined data types
operator math, relational, logic and variable access ...
statement flow control and declaration statements
@@ -50,6 +60,8 @@ Very High priority items:
* Fix any 'Known bugs' as noted in the BUGS file or as
displayed by 'calc help bugs'.
* Copyleft calc and place it under a LGPL.
=-=
High priority items:
@@ -79,10 +91,9 @@ High priority items:
then a $PAGER should be forked and execed after doing things such
as closing open file descriptors that the $PAGER does not need.
* Inspect changes made since the last major calc release (the
initial x.y.z version ... prior to any t sub-version) to help
ensure that they have not introduced new or re-introduced old bugs
into calc.
* The arg passdown to the lower level Makfiles should be reviewed
to determine which items really need to be passed down. The lower
level Makefiles should default to the shipped values.
* Consider using configure to build the calc Makefile.

View File

@@ -4,11 +4,19 @@ Calc Enhancement Wish List:
interesting calc scripts that you would like you see included in
future distributions to:
calc-tester@postofc.corp.sgi.com
calc-tester at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
The following items are in the calc wish list. Programs like this
can be extended and improved forever.
Calc bug reports, however, should be sent to:
calc-bugs at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
See the 'todo' help file for higher priority todo items.
=-=

137
hist.c
View File

@@ -31,6 +31,11 @@
#include "terminal.h"
#include "have_string.h"
#include "have_strdup.h"
#if !defined(HAVE_STRDUP)
# define strdup(x) calc_strdup((CONST char *)(x))
#endif /* HAVE_STRDUP */
#if defined(USE_TERMIOS)
# include <termios.h>
@@ -71,6 +76,7 @@ static struct {
int linelen;
int histcount;
int curhist;
BOOL virgin_line; /* 1 => never typed chars, 0 => chars typed */
} HS;
@@ -245,9 +251,15 @@ static void insert_string(char *str, int len);
int
hist_getline(char *prompt, char *buf, int len)
{
/*
* initialize if we have not already done so
*/
if (!inited)
(void) hist_init(calcbindings);
/*
* establish the beginning of a line condition
*/
HS.prompt = prompt;
HS.bufsize = len - 2;
HS.buf = buf;
@@ -255,19 +267,38 @@ hist_getline(char *prompt, char *buf, int len)
HS.end = buf;
HS.mark = NULL;
HS.linelen = -1;
HS.virgin_line = TRUE;
/*
* prep the I/O
*/
fputs(prompt, stdout);
fflush(stdout);
/*
* special case: non-interactive editing
*/
if (!canedit) {
if (fgets(buf, len, stdin) == NULL)
return 0;
return strlen(buf);
}
while (HS.linelen < 0)
/*
* get the line
*/
while (HS.linelen < 0) {
/* get the next char */
read_key();
/* chars typed, no longer virgin */
HS.virgin_line = FALSE;
}
/*
* return the line
*/
return HS.linelen;
}
@@ -287,12 +318,18 @@ hist_init(char *filename)
{
TTYSTRUCT newtty;
/*
* prevent multiple initializations
*/
if (inited) {
if (conf->calc_debug & CALCDBG_TTY)
printf("DEBUG: inited already set in hist_init\n");
return HIST_INITED;
}
/*
* setup
*/
inited = 1;
canedit = 0;
if (conf->calc_debug & CALCDBG_TTY)
@@ -511,9 +548,9 @@ do_bind_line(KEY_MAP *map, char *line)
} else {
key = CONTROL(*cp++);
}
}
else if (key == '\\')
} else if (key == '\\') {
key = *cp++;
}
while (isspace((int)*cp))
cp++;
@@ -577,8 +614,7 @@ do_default_line(KEY_MAP *map, char *line)
func_name = cp;
while ((*cp != '\0') && !isspace((int)*cp))
cp++;
if (*cp != '\0')
{
if (*cp != '\0') {
*cp++ = '\0';
while (isspace((int)*cp))
cp++;
@@ -587,15 +623,13 @@ do_default_line(KEY_MAP *map, char *line)
if (func == NULL)
return;
if (*cp == '\0')
if (*cp == '\0') {
next = map;
else
{
} else {
next_name = cp;
while ((*cp != '\0') && !isspace((int)*cp))
cp++;
if (*cp != '\0')
{
if (*cp != '\0') {
*cp++ = '\0';
while (isspace((int)*cp))
cp++;
@@ -982,6 +1016,21 @@ forward_kill_char(void)
static void
delete_char(void)
{
/*
* quit delete_char (usually ^D) is at start of line and we are allowed
*
* We exit of start of line and config("ctrl_d", "empty") or
* if config("ctrl_d", "virgin") and we have never typed on the line.
*/
if ((HS.end == HS.buf) &&
(conf->ctrl_d == CTRL_D_EOF ||
(conf->ctrl_d == CTRL_D_VIRGIN && HS.virgin_line == TRUE))) {
quit_calc();
}
/*
* normal case: just forward_kill_char
*/
if (HS.end > HS.buf)
forward_kill_char();
}
@@ -1401,9 +1450,9 @@ beep(void)
static void
echo_char(int ch)
{
if (isprint(ch))
if (isprint(ch)) {
putchar(ch);
else {
} else {
putchar('^');
putchar((ch + '@') & 0x7f);
}
@@ -1440,8 +1489,11 @@ quit_calc(void)
#else /* USE_READLINE */
#include <readline.h>
#include <history.h>
#define HISTORY_LEN (1024) /* number of entries to save */
#include <readline/readline.h>
#include <readline/history.h>
/*
@@ -1454,6 +1506,9 @@ quit_calc(void)
*/
/* name of history file */
char *my_calc_history = NULL;
int
hist_getline(char *prompt, char *buf, int len)
{
@@ -1473,31 +1528,69 @@ hist_getline(char *prompt, char *buf, int len)
}
int
hist_init(char *filename)
{
return HIST_SUCCESS;
}
void
hist_term(void)
{
}
static void
my_stifle_history (void)
{
/* only save last number of entries */
stifle_history(HISTORY_LEN);
if (my_calc_history)
write_history(my_calc_history);
}
int
hist_init(char *filename)
{
/* used when parsing conditionals in ~/.inputrc */
rl_readline_name = "calc";
/* initialize interactive variables */
using_history();
/* name of history file */
my_calc_history = tilde_expand("~/.calc_history");
/* read previous history */
read_history(my_calc_history);
atexit(my_stifle_history);
return HIST_SUCCESS;
}
void
hist_saveline(char *line, int len)
{
if (!len)
static char *prev = NULL;
if (len <= 1)
return;
/* ignore if identical with previous line */
if (prev != NULL && strcmp(prev, line) == 0)
return;
free (prev);
/* fail silently */
prev = strdup(line);
line[len - 1] = '\0';
add_history(line);
line[len - 1] = '\n';
}
#endif /* USE_READLINE */
#if defined(HIST_TEST)
/*

View File

@@ -524,9 +524,9 @@ nextchar(void)
if (cip->i_num) {
ch = chartoint(*cip->i_cp++);
cip->i_num--;
}
else
} else {
ch = EOF;
}
} else if (cip->i_fp) { /* from file */
ch = fgetc(cip->i_fp);
} else if (!stdin_tty) { /* from file */
@@ -908,6 +908,3 @@ addreadset(char *name, char *path, struct stat *sbuf)
/* return index of the newly added entry */
return ret;
}
/* END CODE */

View File

@@ -39,17 +39,22 @@ CALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.cal \
lucas_tbl.cal mersenne.cal mod.cal pell.cal pi.cal pix.cal \
pollard.cal poly.cal psqrt.cal quat.cal regress.cal solve.cal \
sumsq.cal surd.cal unitfrac.cal varargs.cal chrem.cal mfactor.cal \
bindings altbind randmprime.cal test1700.cal randrun.cal \
bindings randmprime.cal test1700.cal randrun.cal \
randbitrun.cal bernoulli.cal test2300.cal test2600.cal \
test2700.cal test3100.cal test3300.cal test3400.cal prompt.cal \
test3500.cal seedrandom.cal test4000.cal test4100.cal test4600.cal \
beer.cal hello.cal test5100.cal test5200.cal randombitrun.cal \
randomrun.cal xx_print.cal natnumset.cal qtime.cal test8400.cal
randomrun.cal xx_print.cal natnumset.cal qtime.cal test8400.cal \
test8500.cal
# These files are found (but not built) in the distribution
#
DISTLIST= ${CALC_FILES} ${MAKE_FILE}
# These files are used to make (but not built) a calc .a library
#
CALCLIBLIST=
all: ${CALC_FILES} ${MAKE_FILE} .all
# used by the upper level Makefile to determine of we have done all
@@ -79,6 +84,13 @@ distlist: ${DISTLIST}
distdir:
${Q}echo lib
calcliblist:
${Q}for i in ${CALCLIBLIST} /dev/null; do \
if [ X"$$i" != X"/dev/null" ]; then \
echo lib/$$i; \
fi; \
done
clean:
clobber:

View File

@@ -2,11 +2,11 @@ To load a library, try:
read filename
You to not need to add the .cal extension to the filename. Calc
You do 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.
most libraries will print out a short message when they are read.
For example:
> read lucas
@@ -33,7 +33,9 @@ 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:
calc-tester@postofc.corp.sgi.com
calc-tester at postofc dot corp dot sgi dot com
[[ Replace 'at' with @, 'dot' is with . and remove the spaces ]]
By convention, a lib file only defines and/or initializes functions,
objects and variables. (The regress.cal and testxxx.cal regression test
@@ -273,10 +275,18 @@ pell.cal
pi.cal
qpi(epsilon)
piforever()
Calculate pi within the specified epsilon using the quartic convergence
iteration.
The qpi() calculate pi within the specified epsilon using the quartic
convergence iteration.
The piforever() prints digits of pi, nicely formatted, for as long
as your free memory space and system up time allows.
The piforever() funcion (written by Klaus Alexander Seistrup
<klaus@seistrup.dk>) was inspired by an algorithm conceived by
Lambert Meertens. See also the ABC Programmer's Handbook, by Geurts,
Meertens & Pemberton, published by Prentice-Hall (UK) Ltd., 1990.
pix.cal
@@ -350,7 +360,7 @@ randbitrun.cal
randbitrun([run_cnt])
Using randbit(1) to generate a sequence of random bits, determine if
the number and kength of identical bits runs match what is expected.
the number and length of identical bits runs match what is expected.
By default, run_cnt is to test the next 65536 random values.
This tests the a55 generator.
@@ -406,7 +416,7 @@ randrun.cal
regress.cal
Test the correct execution of the calculator by reading this library file.
Errors are reported with '****' mssages, or worse. :-)
Errors are reported with '****' messages, or worse. :-)
seedrandom.cal

View File

@@ -1,49 +0,0 @@
# Alternate key bindings for calc line editing functions
#
# NOTE: This facility is ignored if calc was compiled with GNU-readline.
# In that case, the standard readline mechanisms (see readline(3))
# are used in place of those found below.
map base-map
default insert-char
^@ set-mark
^A start-of-line
^B backward-char
^D quit
^E end-of-line
^F forward-char
^H backward-kill-char
^J new-line
^K kill-line
^L refresh-line
^M new-line
^N forward-history
^O save-line
^P backward-history
^R reverse-search
^T swap-chars
^U flush-input
^V quote-char
^W kill-region
^Y yank
^? delete-char
^[ ignore-char esc-map
map esc-map
default ignore-char base-map
G start-of-line
H backward-history
P forward-history
K backward-char
M forward-char
O end-of-line
S delete-char
g goto-line
s backward-word
t forward-word
d forward-kill-word
u uppercase-word
l lowercase-word
h list-history
^[ flush-input
[ arrow-key

View File

@@ -86,7 +86,7 @@
* i.e., any value that is 301 mod 420.
*
* Written by: Ernest W Bowen <ernie@neumann.une.edu.au>
* Interface by: Landon Curt Noll http://reality.sgi.com/chongo
* Interface by: Landon Curt Noll http://reality.sgi.com/chongo/
*/
static defaultmlist = list(2,3,5,7,11,13,17,19); /* The first eight primes */

View File

@@ -20,7 +20,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -20,7 +20,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -20,7 +20,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -20,7 +20,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -159,9 +159,9 @@ define mod_inv(a)
define mod_div(a, b)
{
local c, x, y;
obj mod x, y;
local c;
local obj mod x;
local obj mod y;
if (isnum(a))
a = lmod(a);
if (isnum(b))

View File

@@ -47,3 +47,75 @@ define qpi(epsilon)
}
return (bround(1/an, bits));
}
/*
* Print digits of PI forever, neatly formatted, using calc.
*
* Written by Klaus Alexander Seistrup <klaus@seistrup.dk>
* on a dull Friday evening in November 1999.
*
* Inspired by an algorithm conceived by Lambert Meertens.
*
* See also the ABC Programmer's Handbook, by Geurts, Meertens & Pemberton,
* published by Prentice-Hall (UK) Ltd., 1990.
*
*/
define piforever()
{
local k = 2;
local a = 4;
local b = 1;
local a1 = 12;
local b1 = 4;
local a2, b2, p, q, d, d1;
local stdout = files(1);
local first = 1, row = -1, col = 0;
while (1) {
/*
* Next approximation
*/
p = k * k;
q = k + k++;
a2 = a;
b2 = b;
a = a1;
a1 = p * a2 + q * a1;
b = b1;
b1 = p * b2 + q * b1;
/*
* Print common digits
*/
d = a // b;
d1 = a1 // b1;
while (d == d1) {
if (first) {
printf("%d.", d);
first = 0;
} else {
if (!(col % 50)) {
printf("\n");
col = 0;
if (!(++row % 20)) {
printf("\n");
row = 0;
}
}
printf("%d", d);
if (!(++col % 10))
printf(" ");
}
a = 10 * (a % b);
a1 = 10 * (a1 % b1);
d = a // b;
d1 = a1 // b1;
}
fflush(stdout);
}
}

View File

@@ -471,8 +471,9 @@ define plist(s) {
define deg(a) = size(a.p) - 1;
define polydiv(a,b) {
local q, r, d, u, i, m, n, sa, sb, sq;
obj poly q, r;
local d, u, i, m, n, sa, sb, sq;
local obj poly q;
local obj poly r;
sa=findlist(a); sb = findlist(b); sq = list();
m=size(sa)-1; n=size(sb)-1;
if (n<0) quit "Zero divisor";

View File

@@ -7,7 +7,7 @@
* utc_hr_offset Offset from UTC in hours.
*
* Written by: Klaus Alexander Seistrup <kseis@magnetic-ink.dk>
* With minor mods by: Landon Curt Noll <http://reality.sgi.com/chongo>
* With minor mods by: Landon Curt Noll <http://reality.sgi.com/chongo/>
*
* See:
* http://www.magnetic-ink.dk/download/qtime.html

View File

@@ -22,7 +22,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -385,10 +385,10 @@ define test_config()
'516: config("pow2") == 40');
vrfy(config("redc2") == 50,
'517: config("redc2") == 50');
vrfy(config("tilde") == 1,
'518: config("tilde") == 1');
vrfy(config("tab") == 1,
'519: config("tab") == 1');
vrfy(config("tilde") == "on",
'518: config("tilde") == "on"');
vrfy(config("tab") == "on",
'519: config("tab") == "on"');
vrfy(config("quomod") == 0,
'520: config("quomod") == 0');
vrfy(config("quo") == 2,
@@ -407,10 +407,10 @@ define test_config()
'527: config("outround") == 2');
vrfy(config("round") == 24,
'528: config("round") == 24');
vrfy(config("leadzero") == 0,
'529: config("leadzero") == 0');
vrfy(config("fullzero") == 0,
'530: config("fullzero") == 0');
vrfy(config("leadzero") == "off",
'529: config("leadzero") == "off"');
vrfy(config("fullzero") == "off",
'530: config("fullzero") == "off"');
vrfy(config("maxscan") == 20,
'531: config("maxscan") == 20');
vrfy(config("prompt") == "> ",
@@ -426,10 +426,10 @@ define test_config()
vrfy(config("quo", 0) == 2, '536: config("quo", 0) == 2');
vrfy(config("outround", 24) == 2,
'537: config("outround", 24) == 2');
vrfy(config("leadzero", "y") == 0,
'538: config("leadzero", "y") == 0');
vrfy(config("fullzero", 1) == 0,
'539: config("fullzero", 1) == 0');
vrfy(config("leadzero","y") == "off",
'538: config("leadzero","y") == "off"');
vrfy(config("fullzero", 1) == "off",
'539: config("fullzero", 1) == "off"');
vrfy(config("prompt", "; ") == "> ",
'540: config("prompt", "; ") == "> "');
vrfy(config("more", ";; ") == ">> ",
@@ -441,14 +441,14 @@ define test_config()
'543: config("all",callcfg) == newcfg');
vrfy(config("display",2) == 20,
'544: config("display",2) == 20');
vrfy(config("fullzero",1) == 0,
'545: config("fullzero",1) == 0');
vrfy(config("fullzero",1) == "off",
'545: config("fullzero",1) == "off"');
vrfy(strprintf("%d %d %d", 0, 1, 2) == ".00 1.00 2.00",
'546: strprintf("%d %d %d", 0, 1, 2) == ".00 1.00 2.00"');
vrfy(config("display",20) == 2,
'547: config("display",20) == 2');
vrfy(config("fullzero",0) == 1,
'548: config("fullzero",0) == 1');
vrfy(config("fullzero",0) == "on",
'548: config("fullzero",0) == "on"');
vrfy(strprintf("%d %d %d", 0, 1, 2) == "0 1 2",
'549: strprintf("%d %d %d", 0, 1, 2) == "0 1 2"');
@@ -1582,12 +1582,12 @@ define test_mode()
tmp = config("mode", "int");
print '1604: tmp = config("mode", "int")';
vrfy(tmp == "frac", '1605: tmp == "frac"');
vrfy(tmp == "fraction", '1605: tmp == "fraction"');
vrfy(base() == -10, '1606: base() == -10');
tmp = config("mode", "real");
print '1607: tmp = config("mode", "real")';
vrfy(tmp == "int", '1608: tmp == "int"');
vrfy(tmp == "integer", '1608: tmp == "integer"');
vrfy(base() == 10, '1609: base() == 10');
tmp = config("mode", "exp");
@@ -1597,7 +1597,7 @@ define test_mode()
tmp = config("mode", "hex");
print '1613: tmp = config("mode", "hex")';
vrfy(tmp == "exp", '1614: tmp == "exp"');
vrfy(tmp == "scientific", '1614: tmp == "scientific"');
vrfy(base() == 16, '1615: base() == 16');
tmp = config("mode", "oct");
@@ -1616,11 +1616,13 @@ define test_mode()
tmp = base(1/3);
print '1624: tmp = base(1/3)';
vrfy(config("mode") == "frac", '1625: config("mode") == "frac"');
vrfy(config("mode") == "fraction",
'1625: config("mode") == "fraction"');
tmp = base(-10);
print '1626: tmp = base(-10)';
vrfy(config("mode") == "int", '1627: config("mode") == "int"');
vrfy(config("mode") == "integer",
'1627: config("mode") == "integer"');
tmp = base(10);
print '1628: tmp = base(10)';
@@ -1628,7 +1630,8 @@ define test_mode()
tmp = base(1e20);
print '1630: tmp = base(1e20)';
vrfy(config("mode") == "exp", '1631: config("mode") == "exp"');
vrfy(config("mode") == "scientific",
'1631: config("mode") == "scientific"');
tmp = base(16);
print '1632: tmp = base(16)';
@@ -1694,6 +1697,7 @@ define test_obj()
{
static obj surd a;
static obj surd b;
local PP;
print '1800: Beginning object test';
@@ -1731,7 +1735,10 @@ define test_obj()
vrfy(a <= a, '1828: a < a');
vrfy(isobj(a) == 1, '1829: isobj(a) == 1');
print '1830: Ending object test';
obj pt {x,y}, PP = obj pair {A,B} = {obj pt, obj pt};
print '1830: obj pt {x,y}, PP = obj pair {A,B} = {obj pt, obj pt}';
print '1831: Ending object test';
}
print '028: parsed test_obj()';
@@ -2701,11 +2708,11 @@ define test_matobj()
B[0,0] = res(2);
print '3106: B[0,0] = res(2)';
B[0,1] = res(3);
print '3107: B[0,1] = res(2)';
print '3107: B[0,1] = res(3)';
B[1,0] = res(5);
print '3108: B[1,0] = res(2)';
print '3108: B[1,0] = res(5)';
B[1,1] = res(7);
print '3109: B[1,1] = res(2)';
print '3109: B[1,1] = res(7)';
print '3110: md = 0';
md = 0;
vrfy(det(B) == res(-1), '3111: det(B) == res(-1)');
@@ -2867,7 +2874,7 @@ print '053: parsed test_frem()';
*/
define test_error()
{
local strx, e99, list1, e999;
local strx, e99, list1, e9999;
local a, b, c, n, x; /* used by newerror() */
print '3600: Beginning test_error';
@@ -3040,11 +3047,12 @@ define test_error()
'3710: newerror() == newerror("???")');
vrfy(newerror("") == newerror(),
'3711: newerror("") == newerror()');
e999 = error(999);
print '3712: e999 = error(999)';
vrfy(errno() == 999, '3713: errno() == 999');
vrfy(error() == e999, '3714: error() == e999');
vrfy(strerror() == "Error 999", '3715: strerror() == "Error 999"');
e9999 = error(9999);
print '3712: e9999 = error(9999)';
vrfy(errno() == 9999, '3713: errno() == 9999');
vrfy(error() == e9999, '3714: error() == e9999');
vrfy(substr(strerror(), strpos(strerror(),"9999"), 4) == "9999",
'3715: substr(strerror(), strpos(strerror(),"9999"), 4) == "9999"');
x = newerror("Alpha");
print '3716: x = newerror("Alpha")';
n = iserror(x);
@@ -3052,19 +3060,24 @@ define test_error()
vrfy(errno() == n, '3718: errno() == n');
vrfy(error() == x, '3719: error() == x');
vrfy(strerror() == "Alpha", '3720: strerror() == "Alpha"');
vrfy(errno(999) == n, '3721: errno() == n');
vrfy(errno() == 999, '3722: errno() == 999');
vrfy(error() == e999, '3723: error() == e999');
vrfy(strerror() == "Error 999", '3724: strerror() == "Error 999"');
vrfy(errno(9999) == n, '3721: errno() == n');
vrfy(errno() == 9999, '3722: errno() == 9999');
vrfy(error() == e9999, '3723: error() == e9999');
vrfy(substr(strerror(), strpos(strerror(),"9999"), 4) == "9999",
'3724: substr(strerror(), strpos(strerror(),"9999"), 4) == "9999"');
a = 1/0;
print '3725: a = 1/0';
vrfy(strerror() == "Division by zero",
'3726: strerror() == "Division by zero"');
n = 8191;
print '3727: n = 8191';
vrfy(substr(strerror(8191),strpos(strerror(n),"8191"), 4) == "8191",
'3728: substr(strerror(n),strpos(strerror(n),"8191"),4) == "8191"');
/* errmax and errcount should be bumped up the 148 errors above */
vrfy(errcount() == ecnt, '3727: errcount() == ecnt');
vrfy(errcount() == ecnt, '3729: errcount() == ecnt');
print '3728: Ending test_error';
print '3730: Ending test_error';
}
print '054: parsed test_error()';
@@ -4687,8 +4700,8 @@ define test_commaeq()
/*
* matrix assignment
*/
mat A[3] = {1,2,3}, B[2] = {1,2};
print '5625: mat A[3] = {1,2,3}, B[2] = {1,2}';
mat A[3] = {1,2,3}, mat B[2] = {1,2};
print '5625: mat A[3] = {1,2,3}, mat B[2] = {1,2}';
vrfy(A[0] == 1, '5626: A[0] == 1');
vrfy(B[1] == 2, '5627: B[1] == 2');
@@ -4916,8 +4929,8 @@ define test_assign(base, work)
print base+3: ': X5800 = base+3';
Y5800 = base+4;
print base+4: ': Y5800 = base+4';
obj xy5800 A={1,2}, B={3,4};
print base+5: ': obj xy5800 A={1,2}, B={3,4}';
obj xy5800 A={1,2}, obj xy5800 B={3,4};
print base+5: ': obj xy5800 A={1,2}, obj xy5000 B={3,4}';
/*
* test assignment
@@ -7381,7 +7394,10 @@ X5800 = obj xy5800 = {1,2};
print '5864: X5800 = obj xy5800 = {1,2}';
vrfy(X5800 == (obj xy5800 = {1,2}),
'5865: X5800 == (obj xy5800 = {1,2})');
print '5866: End of 5800 sequence';
define f5800(a5800 = mat[2] = {3,4}) = 5 * a5800;
print '5866: define f5800(a5800 = mat[2] = {3,4}) = 5 * a5800;'
vrfy(f5800() == (mat[] = {15,20}),'5867: f5800() == (mat[] = {15,20})');
print '5868: End of 5800 sequence';
print;
return test_is();
@@ -7482,6 +7498,15 @@ vrfy(test8400() == 64434, '8405: test8400() == 64434');
print '8406: Ending test_quit';
/*
* test_divmod - psuedo-random tests on the // and % with various rounding modes
*/
print;
print '8500: Starting test_divmod'
read -once "test8500";
/* 85xx: Ending test_divmod is printed by test8500.cal */
/*
* read various calc libs
*

View File

@@ -20,7 +20,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*
* Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 2600 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 2700 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 3100 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 3300 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 3400 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 3500 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 4000 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 4100 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 4600 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 5100 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 5200 series of the regress.cal test suite.
*/

View File

@@ -4,7 +4,7 @@
* provided that this copyright notice remains intact.
*
* By: Landon Curt Noll
* http://reality.sgi.com/chongo
* http://reality.sgi.com/chongo/
*
* chongo <was here> /\../\
*

242
lib/test8500.cal Normal file
View File

@@ -0,0 +1,242 @@
/*
* Copyright (c) 1996 Ernest Bowen and Landon Curt Noll
* Permission is granted to use, distribute, or modify this source,
* provided that this copyright notice remains intact.
*
* By: Ernest Bowen and Landon Curt Noll
* ernie@neumann.une.edu.au and http://reality.sgi.com/chongo/
*
* This library is used by the 8500 series of the regress.cal test suite.
*/
/*
* Tests of // and % operators
*/
global err_8500; /* divmod_8500 error count */
global L_8500; /* list of problem values */
global ver_8500; /* test verbosity - see setting comment near bottom */
global old_seed_8500; /* old srand() seed */
/*
* save the config state so that we can change it and restore later
*/
global cfg_8500 = config("all");
/*
* onetest_8500 - perform one division / remainder test
*
* Returns:
* 0 = test was successful
* >0 = test error indicator
*/
define onetest_8500(a,b,rnd) {
local q, r, s, S;
/*
* set a random rounding mode
*/
config("quo", rnd), config("mod", rnd);
/*
* perform the division and mod
*/
q = a // b;
r = a % b;
/*
* verify the fundamental math
*/
if (a != q * b + r)
return 1;
/*
* determine if the rounding worked
*/
if (b) {
if (rnd & 16)
s = sgn(abs(r) - abs(b)/2);
else
s = sgn(abs(r) - abs(b));
if (s < 0 || r == 0)
return 0;
if (s > 0)
return 2;
if (((rnd & 16) && s == 0) || !(rnd & 16)) {
S = sgn(r) * sgn(b); /* This is sgn(a/b) - a//b */
switch (rnd & 15) {
case 0: return (S < 0) ? 3 : 0;
case 1: return (S > 0) ? 4 : 0;
case 2: return (S != sgn(a)*sgn(b)) ? 5 : 0;
case 3: return (S != -sgn(a)*sgn(b)) ? 6 : 0;
break;
case 4: return (S != sgn(b)) ? 7 : 0;
case 5: return (S != -sgn(b)) ? 8 : 0;
case 6: return (S != sgn(a)) ? 9 : 0;
case 7: return (S != -sgn(a)) ? 10 : 0;
case 8: return (isodd(q)) ? 11 : 0;
case 9: return (iseven(q)) ? 12 : 0;
case 10: return (iseven(q) != (a/b > 0)) ? 13:0;
case 11: return (isodd(q) != (a/b > 0)) ? 14:0;
case 12: return (iseven(q) != (b > 0)) ? 15 : 0;
case 13: return (isodd(q) != (b > 0)) ? 16 : 0;
case 14: return (iseven(q) != (a > 0)) ? 17 : 0;
case 15: return (isodd(q) != (a > 0)) ? 18 : 0;
}
}
}
/*
* all is well
*/
return 0;
}
/*
* divmod_8500 - perform a bunch of pseudo-random // and % test
*
* divmod_8500(N, M1, M2) will perform N tests with randomly chosen integers
* a, b with abs(a) < M1, abs(b) < M2, which with 50% probability are
* converted to a = (2 * a + 1) * b, b = 2 * b (to give case where
* a / b is an integer + 1/2).
*
* N defaults to 10, M1 to 2^128, M2 to 2^64
*
* The testnum, if > 0, is used while printing a failure or success.
*
* The rounding parameter is randomly chosen.
*
* After a run of divmod_8500 the a, b, rnd values which gave failure are
* stored in the list L_8500. L_8500[0], L_8500[1], L_8500[2] are a, b, rnd for the first
* test, etc.
*/
define divmod_8500(N = 10, M1 = 2^128, M2 = 2^64, testnum = 0)
{
local a, b, i, v, rnd;
local errmsg; /* error message to display */
/*
* firewall
*/
if (!isint(M1) || M1 < 2)
quit "Bad second arg for dtest";
if (!isint(M2) || M2 < 2)
quit "Bad third arg for dtest";
/*
* test setup
*/
err_8500 = 0;
L_8500 = list();
/*
* perform the random results
*/
for (i = 0; i < N; i++) {
/*
* randomly select two values in the range controlled by M1,M2
*/
a = rand(-M1+1, M1);
b = rand(-M2+1, M2);
if (rand(2)) {
a = (2 * a + 1) * b;
b *= 2;
}
/*
* seelect one of the 32 rounding modes at random
*/
rnd = rand(32);
/*
* ver_8500 pre-test reporting
*/
if (ver_8500 > 1)
printf("Test %d: a = %d, b = %d, rnd = %d\n",
i, a, b, rnd);
/*
* perform the actual test
*/
v = onetest_8500(a, b, rnd);
/*
* individual test analysis
*/
if (v != 0) {
err_8500++;
if (ver_8500 != 0) {
if (testnum > 0) {
errmsg = strprintf(
"Failure %d on test %d", v, i);
prob(errmsg);
} else {
printf("Failure %d on test %d", v, i);
}
}
append(L_8500, a, b, rnd);
}
}
/*
* report in the results
*/
if (err_8500) {
if (testnum > 0) {
errmsg = strprintf(
"%d: divmod_8500(%d,,,%d): %d failures",
testnum, N, testnum, err_8500);
prob(errmsg);
} else {
printf("%s failure%s", err_8500,
(err_8500 > 1) ? "s" : "");
}
} else {
if (testnum > 0) {
errmsg = strprintf("%d: divmod_8500(%d,,,%d)",
testnum, N, testnum);
vrfy(err_8500 == 0, errmsg);
} else {
print "No failure";
}
}
}
/*
* ver_8500 != 0 displays failures; ver_8500 > 1 displays all numbers tested
*/
ver_8500 = 0;
print '8501: ver_8500 = 0';
old_seed_8500 = srand(31^61);
print '8502: old_seed_8500 = srand(31^61)';
/*
* do the tests
*/
divmod_8500(250, 2^128, 2^1, 8503);
divmod_8500(250, 2^128, 2^64, 8504);
divmod_8500(250, 2^256, 2^64, 8505);
divmod_8500(250, 2^1024, 2^64, 8506);
divmod_8500(250, 2^1024, 2^128, 8507);
divmod_8500(250, 2^16384, 2^1024, 8508);
divmod_8500(1000, 2^128, 2^64, 8509);
/*
* restore state
*/
config("all", cfg_8500),;
print '8510: config("all", cfg_8500),';
srand(old_seed_8500),;
print '8511: srand(old_seed_8500),';
/*
* finished with 8500 tests
*/
print '8512: Ending test_divmod';

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