Compare commits

..

7 Commits

Author SHA1 Message Date
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
285 changed files with 3750 additions and 3385 deletions

44
BUGS
View File

@@ -31,23 +31,19 @@ The calc web site is located at:
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.
=-=
@@ -105,12 +106,30 @@ Known bugs:
=-=
Other items of note:
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:
@@ -146,6 +165,7 @@ Other items of note:
DEBUG= -g
or set:
DEBUG=
* 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.

113
CHANGES
View File

@@ -1,4 +1,26 @@
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:.
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:
@@ -212,8 +234,31 @@ Following is the change from calc version 2.11.0t8.9.1 to date:
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.
Following is the change from calc version 2.11.0t8 to 2.11.0t8.9:
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
@@ -369,7 +414,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>)
@@ -517,7 +562,7 @@ Following is the change from calc version 2.11.0t7 to 2.11.0t7.5:
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;
@@ -709,12 +754,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.
@@ -771,7 +816,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:
@@ -1290,7 +1335,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:
@@ -1652,11 +1697,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:
@@ -1794,7 +1839,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.
@@ -1995,7 +2040,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
@@ -2187,7 +2232,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:
@@ -2363,7 +2408,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.
@@ -2525,7 +2570,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().
@@ -2602,7 +2647,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.
@@ -2786,7 +2831,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:
@@ -3071,7 +3116,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.
@@ -3247,7 +3292,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
@@ -3329,7 +3374,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.
@@ -3406,7 +3451,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>.
@@ -3606,7 +3651,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
@@ -3723,7 +3768,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.
@@ -3777,7 +3823,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.
@@ -3880,7 +3927,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.
@@ -4088,7 +4136,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.
@@ -4135,7 +4184,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.
@@ -4256,7 +4306,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.
@@ -4270,12 +4321,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.

140
Makefile
View File

@@ -302,39 +302,6 @@ HAVE_STRDUP=
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
@@ -942,7 +909,7 @@ 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_rusage.h \
have_strdup.h
@@ -957,7 +924,7 @@ 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_rusage.c have_strdup.c
@@ -973,20 +940,20 @@ 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_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 \
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 have_strdup
@@ -2288,98 +2255,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'
@@ -2755,7 +2630,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 ""
@@ -3082,6 +2956,8 @@ 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
${V} echo '=-=-=-=-= end of $@ rule =-=-=-=-='
##
@@ -3249,7 +3125,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
@@ -3430,7 +3305,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

12
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/

View File

@@ -114,6 +114,7 @@ beginfunc(char *name, BOOL newflag)
fp->f_localcount = 0;
fp->f_opcodecount = 0;
fp->f_savedvalue.v_type = V_NULL;
fp->f_savedvalue.v_subtype = V_NOSUBTYPE;
fp->f_name = namestr(&funcnames, newindex);
curfunc = fp;
initlocals();
@@ -461,7 +462,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 +536,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 +639,3 @@ addoplabel(long op, LABEL *label)
addop(op);
uselabel(label);
}
/* END CODE */

View File

@@ -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;
}
@@ -244,8 +245,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 +282,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 +291,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 +447,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 +488,3 @@ compareindices(VALUE *v1, VALUE *v2, long dim)
return TRUE;
}
/* END CODE */

View File

@@ -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++;
}

View File

@@ -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

@@ -570,7 +570,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,9 +614,36 @@ 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:
@@ -626,7 +657,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

@@ -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 */

View File

@@ -1000,6 +1000,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;

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;
}

698
func.c

File diff suppressed because it is too large Load Diff

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:

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

@@ -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:

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 repoers, 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.
=-=

21
hist.c
View File

@@ -516,9 +516,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++;
@@ -582,8 +582,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++;
@@ -592,15 +591,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++;
@@ -1406,9 +1403,9 @@ beep(void)
static void
echo_char(int ch)
{
if (isprint(ch))
if (isprint(ch)) {
putchar(ch);
else {
} else {
putchar('^');
putchar((ch + '@') & 0x7f);
}
@@ -1526,7 +1523,7 @@ hist_saveline(char *line, int len)
{
static char *prev = NULL;
if (!len)
if (len <= 1)
return;
/* ignore if identical with previous line */

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

@@ -44,7 +44,8 @@ CALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.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
#

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
@@ -358,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.
@@ -414,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

@@ -2871,7 +2871,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';
@@ -3044,11 +3044,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(), strlen(strerror())-3, 4) == "9999",
'3715: substr(strerror(), strlen(strerror())-3, 4) == "9999"');
x = newerror("Alpha");
print '3716: x = newerror("Alpha")';
n = iserror(x);
@@ -3056,19 +3057,22 @@ 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(), strlen(strerror())-3, 4) == "9999",
'3724: substr(strerror(), strlen(strerror())-3, 4) == "9999"');
a = 1/0;
print '3725: a = 1/0';
vrfy(strerror() == "Division by zero",
'3726: strerror() == "Division by zero"');
vrfy(substr(strerror(9941), strlen(strerror(9941))-3, 4) == "9941",
'3728: substr(strerror(9941), strlen(strerror(9941))-3, 4) == "9941"');
/* errmax and errcount should be bumped up the 148 errors above */
vrfy(errcount() == ecnt, '3727: errcount() == ecnt');
vrfy(errcount() == ecnt, '3728: errcount() == ecnt');
print '3728: Ending test_error';
print '3729: Ending test_error';
}
print '054: parsed test_error()';
@@ -7385,8 +7389,8 @@ X5800 = obj xy5800 = {1,2};
print '5864: X5800 = obj xy5800 = {1,2}';
vrfy(X5800 == (obj xy5800 = {1,2}),
'5865: X5800 == (obj xy5800 = {1,2})');
define f5800(a8500 = mat[2] = {3,4}) = 5 * a8500;
print '5866: define f5800(a8500 = mat[2] = {3,4}) = 5 * a8500;'
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';
@@ -7489,6 +7493,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
*

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';

View File

@@ -318,17 +318,16 @@ initenv(void)
char *c;
/* determine the $CALCPATH value */
c = getenv(CALCPATH);
calcpath = ((no_env || c == NULL) ? NULL : strdup(c));
c = (no_env ? NULL : getenv(CALCPATH));
calcpath = (c ? strdup(c) : NULL);
if (calcpath == NULL)
calcpath = DEFAULTCALCPATH;
/* determine the $CALCRC value */
c = getenv(CALCRC);
calcrc = ((no_env || c == NULL) ? NULL : strdup(c));
if (calcrc == NULL) {
c = (no_env ? NULL : getenv(CALCRC));
calcrc = (c ? strdup(c) : NULL);
if (calcrc == NULL)
calcrc = DEFAULTCALCRC;
}
if (strlen(calcrc) > MAX_CALCRC) {
math_error("The $CALCRC variable is longer than %d chars",
MAX_CALCRC);
@@ -336,15 +335,14 @@ initenv(void)
}
/* determine the $CALCBINDINGS value */
c = getenv(CALCBINDINGS);
calcbindings = ((no_env || c == NULL) ? NULL : strdup(c));
if (calcbindings == NULL) {
c = (no_env ? NULL : getenv(CALCBINDINGS));
calcbindings = (c ? strdup(c) : NULL);
if (calcbindings == NULL)
calcbindings = DEFAULTCALCBINDINGS;
}
/* determine the $HOME value */
c = getenv(HOME);
home = ((no_env || c == NULL) ? NULL : strdup(c));
c = (no_env ? NULL : getenv(HOME));
home = (c ? strdup(c) : NULL);
if (home == NULL || home[0] == '\0') {
ent = (struct passwd *)getpwuid(geteuid());
if (ent == NULL) {
@@ -356,16 +354,15 @@ initenv(void)
}
/* determine the $PAGER value */
c = getenv(PAGER);
pager = ((no_env || c == NULL) ? NULL : strdup(c));
if (pager == NULL || *pager == '\0') {
c = (no_env ? NULL : getenv(PAGER));
pager = (c ? strdup(c) : NULL);
if (pager == NULL || *pager == '\0')
pager = DEFAULTCALCPAGER;
}
/* determine the $SHELL value */
c = getenv(SHELL);
shell = ((no_env || c == NULL) ? NULL : strdup(c));
if (shell == NULL)
c = (no_env ? NULL : getenv(SHELL));
shell = (c ? strdup(c) : NULL);
if (shell == NULL || *shell == '\0')
shell = DEFAULTSHELL;
}

View File

@@ -35,9 +35,9 @@ insertlistfirst(LIST *lp, VALUE *vp)
ep = elemalloc();
copyvalue(vp, &ep->e_value);
if (lp->l_count == 0)
if (lp->l_count == 0) {
lp->l_last = ep;
else {
} else {
lp->l_cacheindex++;
lp->l_first->e_prev = ep;
ep->e_next = lp->l_first;
@@ -61,9 +61,9 @@ insertlistlast(LIST *lp, VALUE *vp)
ep = elemalloc();
copyvalue(vp, &ep->e_value);
if (lp->l_count == 0)
if (lp->l_count == 0) {
lp->l_first = ep;
else {
} else {
lp->l_last->e_next = ep;
ep->e_prev = lp->l_last;
}
@@ -130,10 +130,12 @@ removelistfirst(LIST *lp, VALUE *vp)
{
if (lp->l_count == 0) {
vp->v_type = V_NULL;
vp->v_subtype = V_NOSUBTYPE;
return;
}
*vp = lp->l_first->e_value;
lp->l_first->e_value.v_type = V_NULL;
lp->l_first->e_value.v_type = V_NOSUBTYPE;
removelistelement(lp, lp->l_first);
}
@@ -151,10 +153,12 @@ removelistlast(LIST *lp, VALUE *vp)
{
if (lp->l_count == 0) {
vp->v_type = V_NULL;
vp->v_subtype = V_NOSUBTYPE;
return;
}
*vp = lp->l_last->e_value;
lp->l_last->e_value.v_type = V_NULL;
lp->l_last->e_value.v_subtype = V_NOSUBTYPE;
removelistelement(lp, lp->l_last);
}
@@ -181,6 +185,7 @@ removelistmiddle(LIST *lp, long index, VALUE *vp)
}
*vp = ep->e_value;
ep->e_value.v_type = V_NULL;
ep->e_value.v_subtype = V_NOSUBTYPE;
removelistelement(lp, ep);
}
@@ -241,8 +246,7 @@ listsegment(LIST *lp, long n1, long n2)
insertlistlast(newlp, &ep->e_value);
ep = ep->e_next;
}
}
else {
} else {
i = n1 - n2 + 1;
while(n2-- > 0 && ep)
ep = ep->e_next;

View File

@@ -154,6 +154,7 @@ matmul(MATRIX *m1, MATRIX *m2)
for (i1 = 0; i1 < max1; i1++) {
for (i2 = 0; i2 < max2; i2++) {
sum.v_type = V_NULL;
sum.v_subtype = V_NOSUBTYPE;
v1 = &m1->m_table[i1 * maxindex];
v2 = &m2->m_table[i2];
for (index = 0; index < maxindex; index++) {
@@ -202,6 +203,7 @@ matsquare(MATRIX *m)
for (i1 = 0; i1 < max; i1++) {
for (i2 = 0; i2 < max; i2++) {
sum.v_type = V_NULL;
sum.v_subtype = V_NOSUBTYPE;
v1 = &m->m_table[i1 * max];
v2 = &m->m_table[i2];
for (index = 0; index < max; index++) {
@@ -405,6 +407,7 @@ matscale(MATRIX *m, long n)
if (n == 0)
return matcopy(m);
temp.v_type = V_NUM;
temp.v_subtype = V_NOSUBTYPE;
temp.v_num = itoq(n);
res = matalloc(m->m_size);
*res = *m;
@@ -436,6 +439,7 @@ matshift(MATRIX *m, long n)
if (n == 0)
return matcopy(m);
temp.v_type = V_NUM;
temp.v_subtype = V_NOSUBTYPE;
temp.v_num = itoq(n);
res = matalloc(m->m_size);
*res = *m;
@@ -1062,6 +1066,7 @@ matdet(MATRIX *m)
while (!testvalue(val)) {
if (--i <= 0) {
tmp1.v_type = V_NUM;
tmp1.v_subtype = V_NOSUBTYPE;
tmp1.v_num = qlink(&_qzero_);
matfree(m);
return tmp1;

3
md5.c
View File

@@ -254,8 +254,7 @@ MD5Final(HASH *state)
SWAP_B8_IN_B32(md5Ctx->data + i,
md5Ctx->data + i);
}
}
else {
} else {
if (count % 4) {
math_error("This should not happen in MD5Final");
/*NOTREACHED*/

11
obj.c
View File

@@ -141,16 +141,20 @@ objcall(int action, VALUE *v1, VALUE *v2, VALUE *v3)
VALUE tmp; /* temp value */
char name[SYMBOLSIZE+1]; /* full name of user routine to call */
/* initialize VALUEs */
val.v_subtype = V_NOSUBTYPE;
tmp.v_subtype = V_NOSUBTYPE;
if ((unsigned)action > OBJ_MAXFUNC) {
math_error("Illegal action for object call");
/*NOTREACHED*/
}
oip = &objectinfo[action];
if (v1->v_type == V_OBJ)
if (v1->v_type == V_OBJ) {
oap = v1->v_obj->o_actions;
else if (v2->v_type == V_OBJ)
} else if (v2->v_type == V_OBJ) {
oap = v2->v_obj->o_actions;
else {
} else {
math_error("Object routine called with non-object");
/*NOTREACHED*/
}
@@ -404,6 +408,7 @@ objpowi(VALUE *vp, NUMBER *q)
case 1:
res.v_obj = objcopy(vp->v_obj);
res.v_type = V_OBJ;
res.v_subtype = V_NOSUBTYPE;
return res;
case -1:
return objcall(OBJ_INV, vp, NULL_VALUE, NULL_VALUE);

119
opcodes.c
View File

@@ -230,6 +230,7 @@ o_argvalue(FUNC *fp, int argcount, VALUE *args)
qfree(stack->v_num);
stack->v_num = itoq((long) argcount);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
index = qtoi(vp->v_num) - 1;
@@ -292,6 +293,7 @@ o_string(FUNC *fp, long arg)
stack++;
stack->v_str = slink(findstring(arg));
stack->v_type = V_STR;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -300,6 +302,7 @@ o_undef(void)
{
stack++;
stack->v_type = V_NULL;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -940,6 +943,7 @@ o_swap(void)
/*NOTREACHED*/
}
stack->v_type = V_NULL;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -958,11 +962,13 @@ o_add(void)
v2 = v2->v_addr;
if (v1->v_type == V_OCTET) {
w1.v_type = V_NUM;
w1.v_subtype = V_NOSUBTYPE;
w1.v_num = itoq(*v1->v_octet);
v1 = &w1;
}
if (v2->v_type == V_OCTET) {
w2.v_type = V_NUM;
w2.v_subtype = V_NOSUBTYPE;
w2.v_num = itoq(*v2->v_octet);
v2 = &w2;
}
@@ -993,11 +999,13 @@ o_sub(void)
v2 = v2->v_addr;
if (v1->v_type == V_OCTET) {
w1.v_type = V_NUM;
w1.v_subtype = V_NOSUBTYPE;
w1.v_num = itoq((unsigned char) *v1->v_octet);
v1 = &w1;
}
if (v2->v_type == V_OCTET) {
w2.v_type = V_NUM;
w2.v_subtype = V_NOSUBTYPE;
w2.v_num = itoq((unsigned char) *v2->v_octet);
v2 = &w2;
}
@@ -1028,11 +1036,13 @@ o_mul(void)
v2 = v2->v_addr;
if (v1->v_type == V_OCTET) {
w1.v_type = V_NUM;
w1.v_subtype = V_NOSUBTYPE;
w1.v_num = itoq(*v1->v_octet);
v1 = &w1;
}
if (v2->v_type == V_OCTET) {
w2.v_type = V_NUM;
w2.v_subtype = V_NOSUBTYPE;
w2.v_num = itoq(*v2->v_octet);
v2 = &w2;
}
@@ -1081,11 +1091,13 @@ o_div(void)
v2 = v2->v_addr;
if (v1->v_type == V_OCTET) {
w1.v_type = V_NUM;
w1.v_subtype = V_NOSUBTYPE;
w1.v_num = itoq(*v1->v_octet);
v1 = &w1;
}
if (v2->v_type == V_OCTET) {
w2.v_type = V_NUM;
w2.v_subtype = V_NOSUBTYPE;
w2.v_num = itoq(*v2->v_octet);
v2 = &w2;
}
@@ -1113,6 +1125,7 @@ o_quo(void)
if (v2->v_type == V_ADDR)
v2 = v2->v_addr;
null.v_type = V_NULL;
null.v_subtype = V_NOSUBTYPE;
quovalue(v1, v2, &null, &tmp);
freevalue(stack--);
freevalue(stack);
@@ -1133,6 +1146,7 @@ o_mod(void)
if (v2->v_type == V_ADDR)
v2 = v2->v_addr;
null.v_type = V_NULL;
null.v_subtype = V_NOSUBTYPE;
modvalue(v1, v2, &null, &tmp);
freevalue(stack--);
freevalue(stack);
@@ -1175,7 +1189,9 @@ o_quomod(void)
}
valquo.v_type = V_NUM;
valquo.v_subtype = V_NOSUBTYPE;
valmod.v_type = V_NUM;
valmod.v_subtype = V_NOSUBTYPE;
res = qquomod(v1->v_num, v2->v_num, &valquo.v_num, &valmod.v_num);
stack -= 2;
if (stack->v_type == V_NUM)
@@ -1185,6 +1201,7 @@ o_quomod(void)
qfree(stack->v_num);
stack->v_num = (res ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
freevalue(v3);
freevalue(v4);
@@ -1289,6 +1306,7 @@ o_not(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qzero_) : qlink(&_qone_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1335,6 +1353,7 @@ o_negate(void)
qfree(stack->v_num);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
negvalue(vp, &tmp);
@@ -1422,8 +1441,7 @@ o_abs(void)
if (v2->v_type == V_ADDR)
v2 = v2->v_addr;
if ((v1->v_type != V_NUM) || (v2->v_type != V_NUM) ||
!qispos(v2->v_num))
{
!qispos(v2->v_num)) {
absvalue(v1, v2, &tmp);
freevalue(stack--);
freevalue(stack);
@@ -1440,6 +1458,7 @@ o_abs(void)
qfree(stack->v_num);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1459,6 +1478,7 @@ o_norm(void)
qfree(stack->v_num);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
normvalue(vp, &tmp);
@@ -1483,6 +1503,7 @@ o_square(void)
qfree(stack->v_num);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
squarevalue(vp, &tmp);
@@ -1503,6 +1524,7 @@ o_test(void)
i = testvalue(vp);
freevalue(stack);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
stack->v_num = i ? qlink(&_qone_) : qlink(&_qzero_);
}
@@ -1534,6 +1556,7 @@ o_links(void)
if (!haveaddress)
links--;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
stack->v_num = itoq(links);
}
@@ -1576,14 +1599,15 @@ o_bit (void)
}
freevalue(stack--);
freevalue(stack);
if (r > 1)
if (r > 1) {
*stack = error_value(E_BIT1);
else if (r < 0)
} else if (r < 0) {
stack->v_type = V_NULL;
else {
} else {
stack->v_type = V_NUM;
stack->v_num = itoq(r);
}
stack->v_subtype = V_NOSUBTYPE;
}
static void
@@ -1628,6 +1652,7 @@ o_highbit (void)
return;
default:
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
stack->v_num = itoq(index);
}
}
@@ -1679,6 +1704,7 @@ o_lowbit (void)
return;
default:
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
stack->v_num = itoq(index);
}
}
@@ -1772,6 +1798,7 @@ o_istype(void)
freevalue(stack);
stack->v_num = itoq((long) r);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1788,6 +1815,7 @@ o_isint(void)
freevalue(stack);
stack->v_num = qlink(&_qzero_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
if (qisint(vp->v_num))
@@ -1798,6 +1826,7 @@ o_isint(void)
qfree(stack->v_num);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1822,10 +1851,12 @@ o_isnum(void)
freevalue(stack);
stack->v_num = qlink(&_qzero_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
stack->v_num = qlink(&_qone_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1841,10 +1872,12 @@ o_ismat(void)
freevalue(stack);
stack->v_num = qlink(&_qzero_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
freevalue(stack);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
stack->v_num = qlink(&_qone_);
}
@@ -1862,6 +1895,7 @@ o_islist(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1878,6 +1912,7 @@ o_isobj(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1894,6 +1929,7 @@ o_isstr(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1910,6 +1946,7 @@ o_isfile(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1926,6 +1963,7 @@ o_isrand(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1942,6 +1980,7 @@ o_israndom(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1958,6 +1997,7 @@ o_isconfig(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1976,6 +2016,7 @@ o_ishash(void)
freevalue(stack);
stack->v_num = itoq((long) r);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -1992,6 +2033,7 @@ o_isassoc(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2012,6 +2054,7 @@ o_isblock(void)
freevalue(stack);
stack->v_num = itoq(r);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2028,6 +2071,7 @@ o_isoctet(void)
freevalue(stack);
stack->v_num = itoq(r);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2050,6 +2094,7 @@ o_isptr(void)
freevalue(stack);
stack->v_num = itoq(r);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2079,6 +2124,7 @@ o_isdefined(void)
freevalue(stack);
stack->v_num = itoq(r);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2099,6 +2145,7 @@ o_isobjtype(void)
freevalue(stack);
stack->v_num = itoq(index >= 0);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2122,6 +2169,7 @@ o_issimple(void)
freevalue(stack);
stack->v_num = (r ? qlink(&_qone_) : qlink(&_qzero_));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2138,11 +2186,13 @@ o_isodd(void)
qfree(stack->v_num);
stack->v_num = qlink(&_qone_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
freevalue(stack);
stack->v_num = qlink(&_qzero_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2159,11 +2209,13 @@ o_iseven(void)
qfree(stack->v_num);
stack->v_num = qlink(&_qone_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
freevalue(stack);
stack->v_num = qlink(&_qzero_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2180,11 +2232,13 @@ o_isreal(void)
qfree(stack->v_num);
stack->v_num = qlink(&_qone_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
freevalue(stack);
stack->v_num = qlink(&_qzero_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2200,11 +2254,13 @@ o_isnull(void)
freevalue(stack);
stack->v_num = qlink(&_qzero_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
freevalue(stack);
stack->v_num = qlink(&_qone_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2221,6 +2277,7 @@ o_re(void)
if (stack->v_type == V_ADDR) {
stack->v_num = qlink(vp->v_num);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
return;
}
@@ -2233,6 +2290,7 @@ o_re(void)
comfree(stack->v_com);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2250,6 +2308,7 @@ o_im(void)
qfree(stack->v_num);
stack->v_num = qlink(&_qzero_);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
if (vp->v_type != V_COM) {
@@ -2261,6 +2320,7 @@ o_im(void)
comfree(stack->v_com);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2277,6 +2337,7 @@ o_conjugate(void)
if (stack->v_type == V_ADDR) {
stack->v_num = qlink(vp->v_num);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
return;
}
@@ -2382,6 +2443,7 @@ o_sgn(void)
qfree(vp->v_num);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
return;
}
sgnvalue(vp, &tmp);
@@ -2410,6 +2472,7 @@ o_numerator(void)
qfree(stack->v_num);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2431,6 +2494,7 @@ o_denominator(void)
qfree(stack->v_num);
stack->v_num = q;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2687,6 +2751,7 @@ o_eq(void)
freevalue(stack);
stack->v_num = itoq((long) (r == 0));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2707,6 +2772,7 @@ o_ne(void)
freevalue(stack);
stack->v_num = itoq((long) (r != 0));
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -2727,15 +2793,15 @@ o_le(void)
freevalue(stack);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
if (tmp.v_type == V_NUM) {
stack->v_num = !qispos(tmp.v_num) ? qlink(&_qone_):
qlink(&_qzero_);
}
else if (tmp.v_type == V_COM) {
} else if (tmp.v_type == V_COM) {
stack->v_num = qlink(&_qzero_);
}
else
} else {
stack->v_type = V_NULL;
}
freevalue(&tmp);
}
@@ -2756,14 +2822,13 @@ o_ge(void)
freevalue(stack--);
freevalue(stack);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
if (tmp.v_type == V_NUM) {
stack->v_num = !qisneg(tmp.v_num) ? qlink(&_qone_):
qlink(&_qzero_);
}
else if (tmp.v_type == V_COM) {
} else if (tmp.v_type == V_COM) {
stack->v_num = qlink(&_qzero_);
}
else {
} else {
stack->v_type = V_NULL;
}
freevalue(&tmp);
@@ -2786,15 +2851,15 @@ o_lt(void)
freevalue(stack--);
freevalue(stack);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
if (tmp.v_type == V_NUM) {
stack->v_num = qisneg(tmp.v_num) ? qlink(&_qone_):
qlink(&_qzero_);
}
else if (tmp.v_type == V_COM) {
} else if (tmp.v_type == V_COM) {
stack->v_num = qlink(&_qzero_);
}
else
} else {
stack->v_type = V_NULL;
}
freevalue(&tmp);
}
@@ -2815,15 +2880,15 @@ o_gt(void)
freevalue(stack--);
freevalue(stack);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
if (tmp.v_type == V_NUM) {
stack->v_num = qispos(tmp.v_num) ? qlink(&_qone_):
qlink(&_qzero_);
}
else if (tmp.v_type == V_COM) {
} else if (tmp.v_type == V_COM) {
stack->v_num = qlink(&_qzero_);
}
else
} else {
stack->v_type = V_NULL;
}
freevalue(&tmp);
}
@@ -2886,6 +2951,7 @@ o_postinc(void)
if (stack->v_type == V_OCTET) {
stack[1] = stack[0];
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
stack->v_num = itoq((long) stack->v_octet[0]);
stack++;
stack->v_octet[0]++;
@@ -2938,8 +3004,8 @@ o_postdec(void)
freevalue(vp);
*vp = tmp;
stack->v_type = V_ADDR;
stack->v_addr = vp;
stack->v_subtype = V_NOSUBTYPE;
stack->v_addr = vp;
}
@@ -3067,6 +3133,7 @@ o_zero(void)
{
stack++;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
stack->v_num = qlink(&_qzero_);
}
@@ -3076,6 +3143,7 @@ o_one(void)
{
stack++;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
stack->v_num = qlink(&_qone_);
}
@@ -3162,6 +3230,7 @@ o_getepsilon(void)
{
stack++;
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
stack->v_num = qlink(conf->epsilon);
}
@@ -3185,6 +3254,7 @@ o_setepsilon(void)
if (stack->v_type == V_NUM)
qfree(newep);
stack->v_type = V_NUM;
stack->v_subtype = V_NOSUBTYPE;
}
@@ -3254,6 +3324,7 @@ updateoldvalue(FUNC *fp)
freevalue(&oldvalue);
oldvalue = fp->f_savedvalue;
fp->f_savedvalue.v_type = V_NULL;
fp->f_savedvalue.v_subtype = V_NOSUBTYPE;
}
@@ -3275,6 +3346,7 @@ error_value(int e)
/*NOTREACHED*/
}
res.v_type = (short) -e;
res.v_subtype = V_NOSUBTYPE;
return res;
}
@@ -3864,6 +3936,3 @@ calclevel(void)
{
return calc_depth - 1;
}
/* END CODE */

50
qfunc.c
View File

@@ -303,35 +303,10 @@ qsqrt(NUMBER *q1, NUMBER *epsilon, long rnd)
if (qiszero(q1))
return qlink(&_qzero_);
sign = (rnd & 64) != 0;
#if 0
if (qiszero(epsilon)) {
s1 = zesqrt(q1->num, &tmp1);
if (s1) {
if (qisint(q1)) {
r = qalloc();
tmp1.sign = sign;
r->num = tmp1;
return r;
}
s2 = zesqrt(q1->den, &tmp2);
if (s2) {
r = qalloc();
tmp1.sign = sign;
r->num = tmp1;
r->den = tmp2;
return r;
}
zfree(tmp2);
}
zfree(tmp1);
return qlink(&_qzero_);
}
#else
if (qiszero(epsilon)) {
math_error("Zero epsilon for qsqrt");
/*NOTREACHED*/
}
#endif
etemp = *epsilon;
etemp.num.sign = 0;
@@ -384,8 +359,7 @@ qsqrt(NUMBER *q1, NUMBER *epsilon, long rnd)
zshift(tmp1, -1, &mul);
up = (*tmp1.v & 1) ? s1 + s2 : -1;
zfree(tmp1);
}
else {
} else {
s1 = zquo(tmp2, divisor, &quo, 0);
zfree(tmp2);
s2 = zsqrt(quo, &mul, 0);
@@ -568,9 +542,9 @@ qilog10(NUMBER *q)
}
/*
* Here if the number is less than one.
* If the number is the inverse of a power of ten, then the obvious answer
* will be off by one. Subtracting one if the number is the inverse of an
* integer will fix it.
* If the number is the inverse of a power of ten, then the
* obvious answer will be off by one. Subtracting one if the
* number is the inverse of an integer will fix it.
*/
if (zisunit(tmp1))
zsub(q->den, _one_, &tmp2);
@@ -1095,8 +1069,7 @@ qcfappr(NUMBER *q, NUMBER *epsilon, long rnd)
zfree(denbnd);
return qlink(q);
}
}
else {
} else {
if (rnd & 16)
epsilon1 = qscale(epsilon, -1);
else
@@ -1107,9 +1080,9 @@ qcfappr(NUMBER *q, NUMBER *epsilon, long rnd)
zfree(tmp1);
qfree(epsilon1);
}
if (rnd & 16 && !zistwo(q->den))
if (rnd & 16 && !zistwo(q->den)) {
s = 0;
else {
} else {
s = esign ? -1 : 1;
if (rnd & 1)
s = -s;
@@ -1164,8 +1137,7 @@ qcfappr(NUMBER *q, NUMBER *epsilon, long rnd)
zfree(tmp1);
}
zfree(denbnd);
}
else {
} else {
if (s < 0) {
zfree(tmp1);
zfree(tmp2);
@@ -1251,9 +1223,9 @@ qcfsim(NUMBER *q, long rnd)
if (qiszero(q) && rnd & 26)
return qlink(&_qzero_);
if (rnd & 24)
if (rnd & 24) {
s = q->num.sign;
else {
} else {
s = rnd & 1;
if (rnd & 2)
s ^= q->num.sign;
@@ -1558,5 +1530,3 @@ qprimetest(NUMBER *q1, NUMBER *q2, NUMBER *q3)
}
return zprimetest(q1->num, ztoi(q2->num), q3->num);
}
/* END CODE */

73
qio.c
View File

@@ -16,11 +16,6 @@
#define PRINTF1(fmt, a1) math_fmt(fmt, a1)
#define PRINTF2(fmt, a1, a2) math_fmt(fmt, a1, a2)
#if 0
static long etoalen;
static char *etoabuf = NULL;
#endif
static long scalefactor;
static ZVALUE scalenumber = { 0, 0, 0 };
@@ -152,72 +147,6 @@ qprintf(char *fmt, ...)
}
#if 0
/*
* Read a number from the specified FILE stream (NULL means stdin).
* The number can be an integer, a fraction, a real number, an
* exponential number, or a hex, octal or binary number. Leading blanks
* are skipped. Illegal numbers return NULL. Unrecognized characters
* remain to be read on the line.
* q = qreadval(fp);
*
* given:
* fp file stream to read from (or NULL)
*/
NUMBER *
qreadval(FILE *fp)
{
NUMBER *r; /* returned number */
char *cp; /* current buffer location */
long savecc; /* characters saved in buffer */
long scancc; /* characters parsed correctly */
int ch; /* current character */
if (fp == NULL)
fp = stdin;
if (etoabuf == NULL) {
etoabuf = (char *)malloc(OUTBUFSIZE + 2);
if (etoabuf == NULL)
return NULL;
etoalen = OUTBUFSIZE;
}
cp = etoabuf;
ch = fgetc(fp);
while ((ch == ' ') || (ch == '\t'))
ch = fgetc(fp);
savecc = 0;
for (;;) {
if (ch == EOF)
return NULL;
if (savecc >= etoalen)
{
cp = (char *)realloc(etoabuf, etoalen + OUTBUFSIZE + 2);
if (cp == NULL)
return NULL;
etoabuf = cp;
etoalen += OUTBUFSIZE;
cp += savecc;
}
*cp++ = (char)ch;
*cp = '\0';
scancc = qparse(etoabuf, QPF_SLASH);
if (scancc != ++savecc)
break;
ch = fgetc(fp);
}
ungetc(ch, fp);
if (scancc < 0)
return NULL;
r = str2q(etoabuf);
if (ziszero(r->den)) {
qfree(r);
r = NULL;
}
return r;
}
#endif
/*
* Print a number in the specified output mode.
* If MODE_DEFAULT is given, then the default output mode is used.
@@ -734,5 +663,3 @@ fitprint(NUMBER *q, long width)
PUTCHAR('/');
fitzprint(q->den, dendigits, width2);
}
/* END CODE */

70
qmath.c
View File

@@ -573,9 +573,9 @@ qquo(NUMBER *q1, NUMBER *q2, long rnd)
if (qiszero(q1) || qiszero(q2))
return qlink(&_qzero_);
if (qisint(q1) && qisint(q2))
if (qisint(q1) && qisint(q2)) {
zquo(q1->num, q2->num, &tmp, rnd);
else {
} else {
zmul(q1->num, q2->den, &tmp1);
zmul(q2->num, q1->den, &tmp2);
zquo(tmp1, tmp2, &tmp, rnd);
@@ -1132,26 +1132,6 @@ qtenpow(long n)
}
#if 0
/*
* Test to see if the specified bit of a number is on (counted from zero).
* Returns TRUE if the bit is set, or FALSE if it is not.
* i = qbittest(q, n);
*/
BOOL
qbittest(NUMBER *q, long n)
{
int x, y;
if ((n < 0) || (n >= (q->num.len * BASEB)))
return FALSE;
x = q->num.v[n / BASEB];
y = (1 << (n % BASEB));
return ((x & y) != 0);
}
#endif
/*
* Return the precision of a number (usually for examining an epsilon value).
* The precision of a number e less than 1 is the positive
@@ -1173,23 +1153,6 @@ qprecision(NUMBER *q)
}
#if 0
/*
* Return an integer indicating the sign of a number (-1, 0, or 1).
* i = qtst(q);
*/
FLAG
qtest(NUMBER *q)
{
if (!ztest(q->num))
return 0;
if (q->num.sign)
return -1;
return 1;
}
#endif
/*
* Determine whether or not one number exactly divides another one.
* Returns TRUE if the first number is an integer multiple of the second one.
@@ -1246,19 +1209,19 @@ qrel(NUMBER *q1, NUMBER *q2)
/*
* Quick check failed, must actually do the full comparison.
*/
if (zisunit(q2->den))
if (zisunit(q2->den)) {
z1 = q1->num;
else if (zisone(q1->num))
} else if (zisone(q1->num)) {
z1 = q2->den;
else {
} else {
z1f = 1;
zmul(q1->num, q2->den, &z1);
}
if (zisunit(q1->den))
if (zisunit(q1->den)) {
z2 = q2->num;
else if (zisone(q2->num))
} else if (zisone(q2->num)) {
z2 = q1->den;
else {
} else {
z2f = 1;
zmul(q2->num, q1->den, &z2);
}
@@ -1382,10 +1345,23 @@ qalloc(void)
}
freeNum[NNALLOC - 1].next = NULL;
freeNum[NNALLOC - 1].links = 0;
for (temp = freeNum + NNALLOC - 2; temp >= freeNum; --temp) {
/*
* We prevent the temp pointer from walking behind freeNum
* by stopping one short of the end and running the loop one
* more time.
*
* We would stop the loop with just temp >= freeNum, but
* doing this helps make code checkers such as insure happy.
*/
for (temp = freeNum + NNALLOC - 2; temp > freeNum; --temp) {
temp->next = temp + 1;
temp->links = 0;
}
/* run the loop manually one last time */
temp->next = temp + 1;
temp->links = 0;
blockcount++;
if (firstNums == NULL) {
newfn = (NUMBER **) malloc(blockcount * sizeof(NUMBER *));
@@ -1457,5 +1433,3 @@ shownumbers(void)
}
printf("\nNumber: %ld\n", count);
}
/* END CODE */

11
qmath.h
View File

@@ -148,17 +148,6 @@ extern void setepsilon(NUMBER *q);
extern NUMBER *qbitvalue(long i);
extern NUMBER *qtenpow(long i);
#if 0
extern NUMBER *qmulmod(NUMBER *q1, NUMBER *q2, NUMBER *q3);
extern NUMBER *qsquaremod(NUMBER *q1, NUMBER *q2);
extern NUMBER *qaddmod(NUMBER *q1, NUMBER *q2, NUMBER *q3);
extern NUMBER *qsubmod(NUMBER *q1, NUMBER *q2, NUMBER *q3);
extern NUMBER *qreadval(FILE *fp);
extern NUMBER *qnegmod(NUMBER *q1, NUMBER *q2);
extern BOOL qbittest(NUMBER *q, long i);
extern FLAG qtest(NUMBER *q);
#endif
/*
* Transcendental functions. These all take an epsilon argument to

120
qmod.c
View File

@@ -108,8 +108,7 @@ qquomod(NUMBER *q1, NUMBER *q2, NUMBER **retqdiv, NUMBER **retqmod)
if (qiszero(q2)) { /* zero modulus case */
qq = qlink(&_qzero_);
qm = qlink(q1);
}
else if (qisint(q1) && qisint(q2)) { /* integer case */
} else if (qisint(q1) && qisint(q2)) { /* integer case */
zdiv(q1->num, q2->num, &tmp1, &tmp2, conf->quomod);
if (ziszero(tmp1)) {
zfree(tmp1);
@@ -127,8 +126,7 @@ qquomod(NUMBER *q1, NUMBER *q2, NUMBER **retqdiv, NUMBER **retqmod)
qm->num = tmp2;
}
}
}
else { /* fractional case */
} else { /* fractional case */
zmul(q1->num, q2->den, &tmp1);
zmul(q2->num, q1->den, &tmp2);
zdiv(tmp1, tmp2, &tmp3, &tmp4, conf->quomod);
@@ -160,118 +158,6 @@ qquomod(NUMBER *q1, NUMBER *q2, NUMBER **retqdiv, NUMBER **retqmod)
}
#if 0
/*
* Return the product of two integers modulo a third integer.
* The result is in the range 0 to q3 - 1 inclusive.
* q4 = (q1 * q2) mod q3.
*/
NUMBER *
qmulmod(NUMBER *q1, NUMBER *q2, NUMBER *q3)
{
NUMBER *q;
if (qisneg(q3) || qiszero(q3))
math_error("Non-positive modulus");
if (qisfrac(q1) || qisfrac(q2) || qisfrac(q3))
math_error("Non-integers for qmulmod");
if (qiszero(q1) || qiszero(q2) || qisunit(q3))
return qlink(&_qzero_);
q = qalloc();
zmulmod(q1->num, q2->num, q3->num, &q->num);
return q;
}
/*
* Return the square of an integer modulo another integer.
* The result is in the range 0 to q2 - 1 inclusive.
* q2 = (q1^2) mod q2.
*/
NUMBER *
qsquaremod(NUMBER *q1, NUMBER *q2)
{
NUMBER *q;
if (qisneg(q2) || qiszero(q2))
math_error("Non-positive modulus");
if (qisfrac(q1) || qisfrac(q2))
math_error("Non-integers for qsquaremod");
if (qiszero(q1) || qisunit(q2))
return qlink(&_qzero_);
if (qisunit(q1))
return qlink(&_qone_);
q = qalloc();
zsquaremod(q1->num, q2->num, &q->num);
return q;
}
/*
* Return the sum of two integers modulo a third integer.
* The result is in the range 0 to q3 - 1 inclusive.
* q4 = (q1 + q2) mod q3.
*/
NUMBER *
qaddmod(NUMBER *q1, NUMBER *q2, NUMBER *q3)
{
NUMBER *q;
if (qisneg(q3) || qiszero(q3))
math_error("Non-positive modulus");
if (qisfrac(q1) || qisfrac(q2) || qisfrac(q3))
math_error("Non-integers for qaddmod");
q = qalloc();
zaddmod(q1->num, q2->num, q3->num, &q->num);
return q;
}
/*
* Return the difference of two integers modulo a third integer.
* The result is in the range 0 to q3 - 1 inclusive.
* q4 = (q1 - q2) mod q3.
*/
NUMBER *
qsubmod(NUMBER *q1, NUMBER *q2, NUMBER *q3)
{
NUMBER *q;
if (qisneg(q3) || qiszero(q3))
math_error("Non-positive modulus");
if (qisfrac(q1) || qisfrac(q2) || qisfrac(q3))
math_error("Non-integers for qsubmod");
if (q1 == q2)
return qlink(&_qzero_);
q = qalloc();
zsubmod(q1->num, q2->num, q3->num, &q->num);
return q;
}
/*
* Return the negative of an integer modulo another integer.
* The result is in the range 0 to q2 - 1 inclusive.
* q2 = (-q1) mod q2.
*/
NUMBER *
qnegmod(NUMBER *q1, NUMBER *q2)
{
NUMBER *q;
if (qisneg(q2) || qiszero(q2))
math_error("Non-positive modulus");
if (qisfrac(q1) || qisfrac(q2))
math_error("Non-integers for qnegmod");
if (qiszero(q1) || qisunit(q2))
return qlink(&_qzero_);
q = qalloc();
znegmod(q1->num, q2->num, &q->num);
return q;
}
#endif
/*
* Return whether or not two integers are congruent modulo a third integer.
* Returns TRUE if the numbers are not congruent, and FALSE if they are.
@@ -521,5 +407,3 @@ freeredcdata(void)
}
}
}
/* END CODE */

View File

@@ -112,9 +112,9 @@ qsincos(NUMBER *q, long bitnum, NUMBER **vs, NUMBER **vc)
if (m > h) {
zshift(cossum, -h, &qtmp1->num);
zbitvalue(m - h, &qtmp1->den);
}
else
} else {
zshift(cossum, - m, &qtmp1->num);
}
zfree(cossum);
*vc = qtmp1;
h = zlowbit(sinsum);
@@ -122,9 +122,9 @@ qsincos(NUMBER *q, long bitnum, NUMBER **vs, NUMBER **vc)
if (m > h) {
zshift(sinsum, -h, &qtmp2->num);
zbitvalue(m - h, &qtmp2->den);
}
else
} else {
zshift(sinsum, -m, &qtmp2->num);
}
zfree(sinsum);
*vs = qtmp2;
return;
@@ -378,8 +378,7 @@ qasin(NUMBER *q, NUMBER *epsilon)
epsilon1 = qscale(epsilon, 1L);
qtmp2 = qpi(epsilon1);
qtmp1 = qscale(qtmp2, -1L);
}
else {
} else {
epsilon1 = qscale(epsilon, -2L);
qtmp1 = qalloc();
zsquare(q->num, &qtmp1->num);
@@ -528,9 +527,9 @@ qatan(NUMBER *q, NUMBER *epsilon)
if (k) {
zshift(sum, -k, &qtmp->num);
zfree(sum);
}
else
} else {
qtmp->num = sum;
}
zbitvalue(m - 4 - k, &qtmp->den);
res = qmappr(qtmp, epsilon, 24L);
qfree(qtmp);
@@ -842,9 +841,9 @@ qexprel(NUMBER *q, long bitnum)
if (zrel(ztmp1, B) >= 0) {
zshift(ztmp1, -m - 1, &sum);
k++;
}
else
} else {
zshift(ztmp1, -m, &sum);
}
zfree(ztmp1);
}
zfree(B);
@@ -957,8 +956,7 @@ qln(NUMBER *q, NUMBER *epsilon)
if (k) {
zshift(sum, -k, &qtmp->num);
zfree(sum);
}
else {
} else {
qtmp->num = sum;
}
zbitvalue(m - k - n, &qtmp->den);
@@ -1003,8 +1001,7 @@ qpower(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
if (zrel(q1->num, q1->den) < 0) {
q1tmp = qinv(q1);
q2tmp = qneg(q2);
}
else {
} else {
q1tmp = qlink(q1);
q2tmp = qlink(q2);
}
@@ -1031,8 +1028,7 @@ qpower(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
tmp2 = qmul(tmp1, &_qlge_);
m = qtoi(tmp2);
}
}
else {
} else {
if (m > 0) {
tmp1 = itoq(m + 1);
tmp2 = qmul(tmp1, q2tmp);
@@ -1070,9 +1066,9 @@ qpower(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
tmp2 = qexprel(tmp1, m - n + 3);
qfree(tmp1);
tmp1 = qinv(tmp2);
}
else
} else {
tmp1 = qexprel(tmp2, m - n + 3) ;
}
qfree(tmp2);
tmp2 = qmappr(tmp1, epsilon, 24L);
qfree(tmp1);
@@ -1240,9 +1236,9 @@ qcoth(NUMBER *q, NUMBER *epsilon)
tmp1 = qmul(&_qlge_, tmp2);
k = qtoi(tmp1);
qfree(tmp1);
}
else
} else {
k = 2 * k;
}
k = 4 - k - n;
if (k < 4)
k = 4;
@@ -1333,9 +1329,9 @@ qcsch(NUMBER *q, NUMBER *epsilon)
tmp2 = qmul(&_qlge_, tmp1);
k = qtoi(tmp2);
qfree(tmp2);
}
else
} else {
k = 2 * qilog2(tmp1);
}
if (k + n >= 1) {
qfree(tmp1);
return qlink(&_qzero_);
@@ -1518,6 +1514,3 @@ qacoth(NUMBER *q, NUMBER *epsilon)
qfree(tmp);
return res;
}
/* END CODE */

3
shs.c
View File

@@ -380,8 +380,7 @@ shsFinal(HASH *state)
for (i=0; i < SHS_CHUNKWORDS; ++i) {
SWAP_B8_IN_B32(dig->data+i, dig->data+i);
}
}
else {
} else {
if (count % 4) {
math_error("This should not happen in shsFinal");
/*NOTREACHED*/

3
shs1.c
View File

@@ -357,8 +357,7 @@ shs1Final(HASH *state)
for (i=0; i < SHS1_CHUNKWORDS; ++i) {
SWAP_B8_IN_B32(dig->data+i, dig->data+i);
}
}
else {
} else {
if (count % 4) {
math_error("This should not happen in shs1Final");
/*NOTREACHED*/

View File

@@ -586,8 +586,7 @@ stringsegment(STRING *s1, long n1, long n2)
if (n1 >= n2) {
while (len-- > 0)
*c++ = *c1--;
}
else {
} else {
while (len-- > 0)
*c++ = *c1++;
}
@@ -640,8 +639,7 @@ stringshift(STRING *s1, long n)
*--c = ((unsigned char) *--c1 >> j) | ch;
ch = (unsigned char) *c1 << k;
}
}
else {
} else {
while (i-- > 0)
*c++ = '\0';
i = len - n;
@@ -979,10 +977,23 @@ stralloc(void)
}
freeStr[STRALLOC - 1].s_next = NULL;
freeStr[STRALLOC - 1].s_links = 0;
for (temp = freeStr + STRALLOC - 2; temp >= freeStr; --temp) {
/*
* We prevent the temp pointer from walking behind freeStr
* by stopping one short of the end and running the loop one
* more time.
*
* We would stop the loop with just temp >= freeStr, but
* doing this helps make code checkers such as insure happy.
*/
for (temp = freeStr + STRALLOC - 2; temp > freeStr; --temp) {
temp->s_next = temp + 1;
temp->s_links = 0;
}
/* run the loop manually one last time */
temp->s_next = temp + 1;
temp->s_links = 0;
blockcount++;
if (firstStrs == NULL) {
newfn = (STRING **) malloc( blockcount * sizeof(STRING *));
@@ -1379,6 +1390,3 @@ showliterals(void)
}
printf("\nNumber: %ld\n", count);
}
/* END CODE */

View File

@@ -345,8 +345,17 @@ freeglobals(void)
GLOBAL *sp; /* current global symbol pointer */
long count; /* number of global variables freed */
/*
* We prevent the hp pointer from walking behind globalhash
* by stopping one short of the end and running the loop one
* more time.
*
* We could stop the loop with just hp >= globalhash, but stopping
* short and running the loop one last time manually helps make
* code checkers such as insure happy.
*/
count = 0;
for (hp = &globalhash[HASHSIZE-1]; hp >= globalhash; hp--) {
for (hp = &globalhash[HASHSIZE-1]; hp > globalhash; hp--) {
for (sp = *hp; sp; sp = sp->g_next) {
if (sp->g_value.v_type != V_NULL) {
freevalue(&sp->g_value);
@@ -354,6 +363,13 @@ freeglobals(void)
}
}
}
/* run the loop manually one last time */
for (sp = *hp; sp; sp = sp->g_next) {
if (sp->g_value.v_type != V_NULL) {
freevalue(&sp->g_value);
count++;
}
}
}
/*
@@ -542,14 +558,22 @@ unscope(void)
register GLOBAL *sp; /* current global symbol pointer */
GLOBAL *prevsp; /* previous kept symbol pointer */
for (hp = &globalhash[HASHSIZE-1]; hp >= globalhash; hp--) {
/*
* We prevent the hp pointer from walking behind globalhash
* by stopping one short of the end and running the loop one
* more time.
*
* We could stop the loop with just hp >= globalhash, but stopping
* short and running the loop one last time manually helps make
* code checkers such as insure happy.
*/
for (hp = &globalhash[HASHSIZE-1]; hp > globalhash; hp--) {
prevsp = NULL;
for (sp = *hp; sp; sp = sp->g_next) {
if ((sp->g_filescope == SCOPE_GLOBAL) ||
(sp->g_filescope < filescope) ||
((sp->g_filescope == filescope) &&
(sp->g_funcscope <= funcscope)))
{
(sp->g_funcscope <= funcscope))) {
prevsp = sp;
continue;
}
@@ -564,6 +588,26 @@ unscope(void)
*hp = sp->g_next;
}
}
/* run the loop manually one last time */
prevsp = NULL;
for (sp = *hp; sp; sp = sp->g_next) {
if ((sp->g_filescope == SCOPE_GLOBAL) ||
(sp->g_filescope < filescope) ||
((sp->g_filescope == filescope) &&
(sp->g_funcscope <= funcscope))) {
prevsp = sp;
continue;
}
/*
* This symbol needs removing.
*/
addstatic(sp);
if (prevsp)
prevsp->g_next = sp->g_next;
else
*hp = sp->g_next;
}
}

22
value.c
View File

@@ -22,8 +22,6 @@
#define LINELEN 80 /* length of a typical tty line */
extern int sys_nerr;
/*
* Free a value and set its type to undefined.
*
@@ -194,6 +192,7 @@ copyvalue(VALUE *oldvp, VALUE *newvp)
break;
case V_OCTET:
newvp->v_type = V_NUM;
newvp->v_subtype = V_NOSUBTYPE;
newvp->v_num = itoq((long) *oldvp->v_octet);
break;
case V_NBLOCK:
@@ -312,6 +311,7 @@ negvalue(VALUE *vp, VALUE *vres)
return;
case V_OCTET:
vres->v_type = V_NUM;
vres->v_subtype = V_NOSUBTYPE;
vres->v_num = itoq(- (long) *vp->v_octet);
return;
@@ -343,6 +343,7 @@ addnumeric(VALUE *v1, VALUE *v2, VALUE *vres)
/*
* add numeric values
*/
vres->v_subtype = V_NOSUBTYPE;
switch (TWOVAL(v1->v_type, v2->v_type)) {
case TWOVAL(V_NUM, V_NUM):
vres->v_num = qqadd(v1->v_num, v2->v_num);
@@ -1541,18 +1542,18 @@ sqrtvalue(VALUE *v1, VALUE *v2, VALUE *v3, VALUE *vres)
copyvalue(v1, vres);
return;
}
if (v2->v_type == V_NULL)
if (v2->v_type == V_NULL) {
q = conf->epsilon;
else {
} else {
if (v2->v_type != V_NUM || qiszero(v2->v_num)) {
*vres = error_value(E_SQRT2);
return;
}
q = v2->v_num;
}
if (v3->v_type == V_NULL)
if (v3->v_type == V_NULL) {
R = conf->sqrt;
else {
} else {
if (v3->v_type != V_NUM || qisfrac(v3->v_num)) {
*vres = error_value(E_SQRT3);
return;
@@ -2420,9 +2421,11 @@ acceptvalue(VALUE *v1, VALUE *v2)
if (fp) {
++stack;
stack->v_type = V_ADDR;
stack->v_subtype = V_NOSUBTYPE;
stack->v_addr = v1;
++stack;
stack->v_type = V_ADDR;
stack->v_subtype = V_NOSUBTYPE;
stack->v_addr = v2;
calculate(fp, 2);
ret = testvalue(stack);
@@ -2447,9 +2450,11 @@ precvalue(VALUE *v1, VALUE *v2)
if (fp) {
++stack;
stack->v_type = V_ADDR;
stack->v_subtype = V_NOSUBTYPE;
stack->v_addr = v1;
++stack;
stack->v_type = V_ADDR;
stack->v_subtype = V_NOSUBTYPE;
stack->v_addr = v2;
calculate(fp, 2);
ret = testvalue(stack);
@@ -2632,6 +2637,7 @@ sgnvalue(VALUE *vp, VALUE *vres)
switch (vp->v_type) {
case V_NUM:
vres->v_num = qsign(vp->v_num);
vres->v_subtype = vp->v_subtype;
return;
case V_COM:
c = comalloc();
@@ -2641,9 +2647,11 @@ sgnvalue(VALUE *vp, VALUE *vres)
c->imag = qsign(vp->v_com->imag);
vres->v_com = c;
vres->v_type = V_COM;
vres->v_subtype = V_NOSUBTYPE;
return;
case V_OCTET:
vres->v_type = V_NUM;
vres->v_subtype = V_NOSUBTYPE;
vres->v_num = itoq((long) (*vp->v_octet != 0));
return;
case V_OBJ:
@@ -2694,7 +2702,7 @@ printvalue(VALUE *vp, int flags)
if (type < 0) {
if (userfunc("error_print", vp))
return;
if (-type >= sys_nerr)
if (-type >= E__BASE)
printf("Error %d", -type);
else
printf("System error %d", -type);

View File

@@ -18,7 +18,7 @@ static char *program;
#define MAJOR_VER 2 /* major version */
#define MINOR_VER 11 /* minor version */
#define MAJOR_PATCH 0 /* patch level or 0 if no patch */
#define MINOR_PATCH "9.4.2" /* test number or empty string if no patch */
#define MINOR_PATCH "10.1.2" /* test number or empty string if no patch */
/*
* calc version constants

164
zfunc.c
View File

@@ -611,61 +611,6 @@ zmodinv(ZVALUE u, ZVALUE v, ZVALUE *res)
}
#if 0
/*
* Approximate the quotient of two integers by another set of smaller
* integers. This uses continued fractions to determine the smaller set.
*/
void
zapprox(ZVALUE z1, ZVALUE z2, ZVALUE *res1, ZVALUE *res2)
{
int sign;
ZVALUE u1, v1, u3, v3, q, t1, t2, t3;
sign = ((z1.sign != 0) ^ (z2.sign != 0));
z1.sign = 0;
z2.sign = 0;
v3 = z2;
u3 = z1;
u1 = _one_;
v1 = _zero_;
while (!ziszero(v3)) {
zdiv(u3, v3, &q, &t1, 0);
zmul(v1, q, &t2);
zsub(u1, t2, &t3);
zfree(q);
zfree(t2);
zfree(u1);
if ((u3.v != z1.v) && (u3.v != z2.v))
zfree(u3);
u1 = v1;
u3 = v3;
v1 = t3;
v3 = t1;
}
if (!zisunit(u3)) {
math_error("Non-relativly prime numbers for approx");
/*NOTREACHED*/
}
if ((u3.v != z1.v) && (u3.v != z2.v))
zfree(u3);
if ((v3.v != z1.v) && (v3.v != z2.v))
zfree(v3);
zfree(v1);
zmul(u1, z1, &t1);
zsub(t1, _one_, &t2);
zfree(t1);
zquo(t2, z2, &t1, 0);
zfree(t2);
u1.sign = (BOOL)sign;
t1.sign = 0;
*res1 = t1;
*res2 = u1;
}
#endif
/*
* Compute the greatest common divisor of a pair of integers.
*/
@@ -784,8 +729,9 @@ zgcd(ZVALUE z1, ZVALUE z2, ZVALUE *res)
*a++ = (HALF) f;
}
if (f >>= BASEB) {len++; *a = (HALF) f;}
} else {
memcpy(gcd.v + o, b0, n * sizeof(HALF));
}
else memcpy(gcd.v + o, b0, n * sizeof(HALF));
gcd.len = len;
gcd.sign = 0;
freeh(A);
@@ -962,9 +908,12 @@ zgcd(ZVALUE z1, ZVALUE z2, ZVALUE *res)
*a++ = (HALF) f;
f >>= BASEB;
}
if (f) {len++; *a = (HALF) f;}
if (f) {
len++; *a = (HALF) f;
}
} else {
memcpy(gcd.v + o, b0, n * sizeof(HALF));
}
else memcpy(gcd.v + o, b0, n * sizeof(HALF));
gcd.len = len;
gcd.sign = 0;
freeh(A);
@@ -1109,7 +1058,17 @@ zlog(ZVALUE z1, ZVALUE z2)
*/
val = _one_;
power = 0;
for (; zp >= squares; zp--, worth /= 2) {
/*
* We prevent the zp pointer from walking behind squares
* by stopping one short of the end and running the loop one
* more time.
*
* We could stop the loop with just zp >= squares, but stopping
* short and running the loop one last time manually helps make
* code checkers such as insure happy.
*/
for (; zp > squares; zp--, worth /= 2) {
if ((val.len + zp->len - 1) <= z1.len) {
zmul(val, *zp, &temp);
if (zrel(z1, temp) >= 0) {
@@ -1123,6 +1082,22 @@ zlog(ZVALUE z1, ZVALUE z2)
if (zp != squares)
zfree(*zp);
}
/* run the loop manually one last time */
if (zp == squares) {
if ((val.len + zp->len - 1) <= z1.len) {
zmul(val, *zp, &temp);
if (zrel(z1, temp) >= 0) {
zfree(val);
val = temp;
power += worth;
} else {
zfree(temp);
}
}
if (zp != squares)
zfree(*zp);
}
zfree(val);
return power;
}
@@ -1163,7 +1138,17 @@ zlog10(ZVALUE z)
*/
val = _one_;
power = 0;
for (; zp >= _tenpowers_; zp--, worth /= 2) {
/*
* We prevent the zp pointer from walking behind _tenpowers_
* by stopping one short of the end and running the loop one
* more time.
*
* We could stop the loop with just zp >= _tenpowers_, but stopping
* short and running the loop one last time manually helps make
* code checkers such as insure happy.
*/
for (; zp > _tenpowers_; zp--, worth /= 2) {
if ((val.len + zp->len - 1) <= z.len) {
zmul(val, *zp, &temp);
if (zrel(z, temp) >= 0) {
@@ -1175,6 +1160,20 @@ zlog10(ZVALUE z)
}
}
}
/* run the loop manually one last time */
if (zp == _tenpowers_) {
if ((val.len + zp->len - 1) <= z.len) {
zmul(val, *zp, &temp);
if (zrel(z, temp) >= 0) {
zfree(val);
val = temp;
power += worth;
} else {
zfree(temp);
}
}
}
zfree(val);
return power;
}
@@ -1281,11 +1280,21 @@ zfacrem(ZVALUE z1, ZVALUE z2, ZVALUE *rem)
worth *= 2;
count += worth;
}
/*
* Now back down the list of squares, and see if the lower powers
* will divide any more times.
*/
for (; zp >= squares; zp--, worth /= 2) {
/*
* We prevent the zp pointer from walking behind squares
* by stopping one short of the end and running the loop one
* more time.
*
* We could stop the loop with just zp >= squares, but stopping
* short and running the loop one last time manually helps make
* code checkers such as insure happy.
*/
for (; zp > squares; zp--, worth /= 2) {
if (zp->len <= z1.len) {
zdiv(z1, *zp, &temp1, &temp2, 0);
if (ziszero(temp2)) {
@@ -1300,6 +1309,23 @@ zfacrem(ZVALUE z1, ZVALUE z2, ZVALUE *rem)
if (zp != squares)
zfree(*zp);
}
/* run the loop manually one last time */
if (zp == squares) {
if (zp->len <= z1.len) {
zdiv(z1, *zp, &temp1, &temp2, 0);
if (ziszero(temp2)) {
temp3 = z1;
z1 = temp1;
temp1 = temp3;
count += worth;
}
zfree(temp1);
zfree(temp2);
}
if (zp != squares)
zfree(*zp);
}
*rem = z1;
return count;
}
@@ -1458,8 +1484,7 @@ zsqrt(ZVALUE z, ZVALUE *dest, long rnd)
f = A[1];
g = (FULL) A[0] << (j + BASEB);
d = e = topbit = (FULL)1 << (k - 1);
}
else {
} else {
if (j)
f = (FULL) A[m-1] << (j + BASEB) | (FULL) A[m-2] << j |
A[m-3] >> k;
@@ -1532,8 +1557,7 @@ zsqrt(ZVALUE z, ZVALUE *dest, long rnd)
A[m1 - 4] = (HALF)f;
m = m1 - 2;
k1 = k + 1;
}
else {
} else {
A[m1 - 1] = 1;
A[m1 - 2] = (HALF)(e >> (BASEB - 1));
A[m1 - 3] = ((HALF)(e << 1) | (HALF)(s > 0));
@@ -1590,9 +1614,9 @@ zsqrt(ZVALUE z, ZVALUE *dest, long rnd)
a[1] |= 1;
}
*a = ((HALF)(x << 1) | (HALF)(u > 0));
}
else
} else {
*a = u;
}
m--;
if (*--a == u) {
while (m > 1 && *--a == u)
@@ -1665,9 +1689,9 @@ done: if (s == 0) {
n++;
*a = 1;
}
}
else
} else {
remsign = 1;
}
sqrt.v = alloc(n);
sqrt.len = n;
sqrt.sign = 0;
@@ -1826,5 +1850,3 @@ zissquare(ZVALUE z)
zfree(tmp);
return (n ? TRUE : FALSE);
}
/* END CODE */

57
zmath.c
View File

@@ -733,24 +733,24 @@ done: while (m > 0 && A[m - 1] == 0)
f = g = 0;
t = -1;
if (s) {
while (--i > 0 ) {
while (--i > 0) {
g = (FULL) *--a + (*--b >> 1 | f);
f = *b & 1 ? TOPHALF : 0;
if (g != BASE1)
break;
f = *b & 1 ? TOPHALF : 0;
}
if (g == BASE && f == 0) {
while (i-- && (*a-- | *b--) == 0);
while ((--i > 0) && ((*--a | *--b) == 0));
t = (i > 0);
}
else if (g >= BASE)
} else if (g >= BASE) {
t = 1;
}
} else {
while (--i > 0) {
g = (FULL) *--a - (*--b >> 1 | f);
f = *b & 1 ? TOPHALF : 0;
if (g != 0)
break;
f = *b & 1 ? TOPHALF : 0;
}
if (g > 0 && g < BASE)
t = 1;
@@ -816,9 +816,9 @@ done: while (m > 0 && A[m - 1] == 0)
val = rem->sign ? -1 : 1;
if (a1[len - 1] == 0)
len--;
if (len == 0)
if (len == 0) {
*quo = _zero_;
else {
} else {
quo->len = len;
quo->v = alloc(len);
memcpy(quo->v, a1, len * sizeof(HALF));
@@ -1318,8 +1318,7 @@ zxor(ZVALUE z1, ZVALUE z2, ZVALUE *res)
j = z1.len;
h1 = z2.v;
h2 = z1.v;
}
else if (z1.len == z2.len) {
} else if (z1.len == z2.len) {
while (len > 1 && z1.v[len-1] == z2.v[len-1])
len--;
j = len;
@@ -1353,8 +1352,7 @@ zandnot(ZVALUE z1, ZVALUE z2, ZVALUE *res)
len--;
j = len;
k = 0;
}
else {
} else {
j = z2.len;
k = len - z2.len;
}
@@ -1505,41 +1503,6 @@ zhighbit(ZVALUE z)
}
#if 0
/*
* Reverse the bits of a particular range of bits of a number.
*
* This function returns an integer with bits a thru b swapped.
* That is, bit a is swapped with bit b, bit a+1 is swapped with b-1,
* and so on.
*
* As a special case, if the ending bit position is < 0, is it taken to
* mean the highest bit set. Thus zbitrev(0, -1, z, &res) will
* perform a complete bit reverse of the number 'z'.
*
* As a special case, if the starting bit position is < 0, is it taken to
* mean the lowest bit set. Thus zbitrev(-1, -1, z, &res) is the
* same as zbitrev(lowbit(z), highbit(z), z, &res).
*
* Note that the low order bit number is taken to be 0. Also, bitrev
* ignores the sign of the number.
*
* Bits beyond the highest bit are taken to be zero. Thus the calling
* bitrev(0, 100, _one_, &res) will result in a value of 2^100.
*
* given:
* low lowest bit to reverse, <0 => lowbit(z)
* high highest bit to reverse, <0 => highbit(z)
* z value to bit reverse
* res resulting bit reverse number
*/
void
zbitrev(long low, long high, ZVALUE z, ZVALUE *res)
{
}
#endif
/*
* Return whether or not the specifed bit number is set in a number.
* Rightmost bit of a number is bit 0.

View File

@@ -349,11 +349,6 @@ extern void zlcmfact(ZVALUE z, ZVALUE *dest);
/*
* Misc misc functions. :-)
*/
#if 0
extern void zapprox(ZVALUE z1, ZVALUE z2, ZVALUE *res1, ZVALUE *res2);
extern void zmulmod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res);
extern void zsubmod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res);
#endif
extern void zsquaremod(ZVALUE z1, ZVALUE z2, ZVALUE *res);
extern void zminmod(ZVALUE z1, ZVALUE z2, ZVALUE *res);
extern BOOL zcmpmod(ZVALUE z1, ZVALUE z2, ZVALUE z3);

238
zmod.c
View File

@@ -30,76 +30,6 @@ BOOL havelastmod = FALSE;
static ZVALUE lastmod[1];
static ZVALUE lastmodinv[1];
#if 0
extern void zaddmod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res);
extern void znegmod(ZVALUE z1, ZVALUE z2, ZVALUE *res);
/*
* Multiply two numbers together and then mod the result with a third number.
* The two numbers to be multiplied can be negative or out of modulo range.
* The result will be in the range 0 to the modulus - 1.
*
* given:
* z1 first number to be multiplied
* z2 second number to be multiplied
* z3 number to take mod with
* res result
*/
void
zmulmod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
{
ZVALUE tmp;
FULL prod;
FULL digit;
BOOL neg;
if (ziszero(z3) || zisneg(z3))
math_error("Mod of non-positive integer");
/*NOTREACHED*/
if (ziszero(z1) || ziszero(z2) || zisunit(z3)) {
*res = _zero_;
return;
}
/*
* If the modulus is a single digit number, then do the result
* cheaply. Check especially for a small power of two.
*/
if (zistiny(z3)) {
neg = (z1.sign != z2.sign);
digit = z3.v[0];
if ((digit & -digit) == digit) { /* NEEDS 2'S COMP */
prod = ((FULL) z1.v[0]) * ((FULL) z2.v[0]);
prod &= (digit - 1);
} else {
z1.sign = 0;
z2.sign = 0;
prod = (FULL) zmodi(z1, (long) digit);
prod *= (FULL) zmodi(z2, (long) digit);
prod %= digit;
}
if (neg && prod)
prod = digit - prod;
itoz((long) prod, res);
return;
}
/*
* The modulus is more than one digit.
* Actually do the multiply and divide if necessary.
*/
zmul(z1, z2, &tmp);
if (zispos(tmp) && ((tmp.len < z3.len) || ((tmp.len == z3.len) &&
(tmp.v[tmp.len-1] < z2.v[z3.len-1]))))
{
*res = tmp;
return;
}
zmod(tmp, z3, res, 0);
zfree(tmp);
}
#endif
/*
* Square a number and then mod the result with a second number.
@@ -159,154 +89,6 @@ zsquaremod(ZVALUE z1, ZVALUE z2, ZVALUE *res)
}
#if 0
/*
* Add two numbers together and then mod the result with a third number.
* The two numbers to be added can be negative or out of modulo range.
* The result will be in the range 0 to the modulus - 1.
*
* given:
* z1 first number to be added
* z2 second number to be added
* z3 number to take mod with
* res result
*/
static void
zaddmod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
{
ZVALUE tmp;
FULL sumdigit;
FULL moddigit;
if (ziszero(z3) || zisneg(z3))
math_error("Mod of non-positive integer");
/*NOTREACHED*/
if ((ziszero(z1) && ziszero(z2)) || zisunit(z3)) {
*res = _zero_;
return;
}
if (zistwo(z2)) {
if ((z1.v[0] + z2.v[0]) & 0x1)
*res = _one_;
else
*res = _zero_;
return;
}
zadd(z1, z2, &tmp);
if (zisneg(tmp) || (tmp.len > z3.len)) {
zmod(tmp, z3, res, 0);
zfree(tmp);
return;
}
sumdigit = tmp.v[tmp.len - 1];
moddigit = z3.v[z3.len - 1];
if ((tmp.len < z3.len) || (sumdigit < moddigit)) {
*res = tmp;
return;
}
if (sumdigit < 2 * moddigit) {
zsub(tmp, z3, res);
zfree(tmp);
return;
}
zmod(tmp, z2, res, 0);
zfree(tmp);
}
/*
* Subtract two numbers together and then mod the result with a third number.
* The two numbers to be subtract can be negative or out of modulo range.
* The result will be in the range 0 to the modulus - 1.
*
* given:
* z1 number to be subtracted from
* z2 number to be subtracted
* z3 number to take mod with
* res result
*/
void
zsubmod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
{
if (ziszero(z3) || zisneg(z3)) {
math_error("Mod of non-positive integer");
/*NOTREACHED*/
}
if (ziszero(z2)) {
zmod(z1, z3, res, 0);
return;
}
if (ziszero(z1)) {
znegmod(z2, z3, res);
return;
}
if ((z1.sign == z2.sign) && (z1.len == z2.len) &&
(z1.v[0] == z2.v[0]) && (zcmp(z1, z2) == 0)) {
*res = _zero_;
return;
}
z2.sign = !z2.sign;
zaddmod(z1, z2, z3, res);
}
/*
* Calculate the negative of a number modulo another number.
* The number to be negated can be negative or out of modulo range.
* The result will be in the range 0 to the modulus - 1.
*
* given:
* z1 number to take negative of
* z2 number to take mod with
* res result
*/
static void
znegmod(ZVALUE z1, ZVALUE z2, ZVALUE *res)
{
int sign;
int cv;
if (ziszero(z2) || zisneg(z2)) {
math_error("Mod of non-positive integer");
/*NOTREACHED*/
}
if (ziszero(z1) || zisunit(z2)) {
*res = _zero_;
return;
}
if (zistwo(z2)) {
if (z1.v[0] & 0x1)
*res = _one_;
else
*res = _zero_;
return;
}
/*
* If the absolute value of the number is within the modulo range,
* then the result is just a copy or a subtraction. Otherwise go
* ahead and negate and reduce the result.
*/
sign = z1.sign;
z1.sign = 0;
cv = zrel(z1, z2);
if (cv == 0) {
*res = _zero_;
return;
}
if (cv < 0) {
if (sign)
zcopy(z1, res);
else
zsub(z2, z1, res);
return;
}
z1.sign = !sign;
zmod(z1, z2, res, 0);
}
#endif
/*
* Calculate the number congruent to the given number whose absolute
* value is minimal. The number to be reduced can be negative or out of
@@ -477,8 +259,7 @@ zcmpmod(ZVALUE z1, ZVALUE z2, ZVALUE z3)
*/
if ((tmp1.sign == tmp2.sign) &&
((tmp1.len < len) || (zrel(tmp1, z3) < 0)) &&
((tmp2.len < len) || (zrel(tmp2, z3) < 0)))
{
((tmp2.len < len) || (zrel(tmp2, z3) < 0))) {
if (tmp1.v != z1.v)
zfree(tmp1);
if (tmp2.v != z2.v)
@@ -747,8 +528,7 @@ zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
/*
* If modulus is large enough use zmod5
*/
if (z3.len >= conf->pow2)
{
if (z3.len >= conf->pow2) {
if (havelastmod && zcmp(z3, *lastmod)) {
zfree(*lastmod);
zfree(*lastmodinv);
@@ -869,8 +649,7 @@ zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
* If the modulus is odd and small enough then use
* the REDC algorithm. The size where this is done is configurable.
*/
if (z3.len < conf->redc2 && zisodd(z3))
{
if (z3.len < conf->redc2 && zisodd(z3)) {
if (powermodredc && zcmp(powermodredc->mod, z3)) {
zredcfree(powermodredc);
powermodredc = NULL;
@@ -1283,8 +1062,7 @@ zredcdecode(REDC *rp, ZVALUE z1, ZVALUE *res)
if (len == 0)
len = 1;
res->len = len;
}
else {
} else {
/* Here 0 < z1 < 2^bitnum */
/*
@@ -1318,9 +1096,9 @@ zredcdecode(REDC *rp, ZVALUE z1, ZVALUE *res)
zp1.len = tmp1.len - modlen;
zp1.sign = 0;
zadd(zp1, _one_, res);
}
else
} else {
*res = _one_;
}
zfree(tmp1);
}
if (ztop.len) {
@@ -2033,9 +1811,9 @@ zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res)
if (sign && !ziszero(ans)) {
zsub(rp->mod, ans, res);
zfree(ans);
}
else
} else {
*res = ans;
}
if (ztmp.len)
zfree(ztmp);
}

72
zmul.c
View File

@@ -280,6 +280,8 @@ domul(HALF *v1, LEN size1, HALF *v2, LEN size2, HALF *ans)
baseA = v1 + shift;
baseB = v1;
/*
* XXX - is this still an issue?
*
* Saber-C Version 3.1 says:
*
* W#26, Storing a bad pointer into auto variable dmul`baseC.
@@ -296,11 +298,13 @@ domul(HALF *v1, LEN size1, HALF *v2, LEN size2, HALF *ans)
* config("mul2", 2);
* pmod(3,a-1,a);
*
* [[ NOTE: The above code no longer invokes this code. ]]
*
* When this code is executed, shift == 6 and v2 is 3 shorts
* long (size2 == 2). This baseC points 3 shorts beyond the
* allocated end of v2.
*
* The stack was as follows:
* The stack was as follows: [[NOTE: line numbers may have changed]]
*
* domul(v1=0x2d93d8, size1=12,
* v2=0x2ded30, size2=2, ans=0x2ee8a8) at "zmul.c":313
@@ -314,6 +318,64 @@ domul(HALF *v1, LEN size1, HALF *v2, LEN size2, HALF *ans)
* evaluate(...) at "codegen.c":170
* getcommands(...) at "codegen.c":109
* main(...) at "calc.c":167
*
* The final domul() call point is the next executable line below.
*
****
*
* The insure tool also reports a problem at this position:
*
* [zmul.c:319] **COPY_BAD_RANGE**
* >> baseC = v2 + shift;
*
* Copying pointer which is out-of-range: v2 + shift
*
* [[NOTE: line numbers may have changed]]
*
* Pointer : 0x1400919cc
* Actual block : 0x140090c80 thru 0x140090def (368 bytes,92 elements)
* hp, allocated at:
* malloc()
* alloc() zmath.c, 221
* zmul() zmul.c, 73
* ztenpow() zfunc.c, 441
* str2q() qio.c, 537
* addnumber() const.c, 52
* eatnumber() token.c, 594
* gettoken() token.c, 319
* getcallargs() codegen.c, 2358
*
* Stack trace where the error occurred:
* domul() zmul.c, 319
* zmul() zmul.c, 74
* ztenpow() zfunc.c, 441
* str2q() qio.c, 537
* addnumber() const.c, 52
* eatnumber() token.c, 594
* gettoken() token.c, 319
* getcallargs() codegen.c, 2358
* getidexpr() codegen.c, 1998
* getterm() codegen.c, 1936
* getincdecexpr() codegen.c, 1820
* getreference() codegen.c, 1804
* getshiftexpr() codegen.c, 1758
* getandexpr() codegen.c, 1704
* getorexpr() codegen.c, 1682
* getproduct() codegen.c, 1654
* getsum() codegen.c, 1626
* getrelation() codegen.c, 1585
* getandcond() codegen.c, 1556
* getorcond() codegen.c, 1532
* getaltcond() codegen.c, 1499
* getassignment() codegen.c, 1442
* getopassignment() codegen.c, 1352
* getexprlist() codegen.c, 1318
* getstatement() codegen.c, 921
* evaluate() codegen.c, 219
* getcommands() codegen.c, 165
* main() calc.c, 321
*
* The final domul() call point is the next executable line below.
*/
/* ok to ignore on name domul`baseC */
baseC = v2 + shift;
@@ -473,8 +535,7 @@ domul(HALF *v1, LEN size1, HALF *v2, LEN size2, HALF *ans)
h2--;
}
}
if ((sizeC > sizeD) || ((sizeC == sizeD) && (*h1 > *h2)))
{
if ((sizeC > sizeD) || ((sizeC == sizeD) && (*h1 > *h2))) {
neg = !neg;
h1 = baseC;
h2 = baseD;
@@ -984,8 +1045,7 @@ dosquare(HALF *vp, LEN size, HALF *ans)
h2--;
}
}
if ((sizeA > sizeB) || ((sizeA == sizeB) && (*h1 > *h2)))
{
if ((sizeA > sizeB) || ((sizeA == sizeB) && (*h1 > *h2))) {
h1 = baseA;
h2 = baseB;
sizeAB = sizeA;
@@ -1093,5 +1153,3 @@ zalloctemp(LEN len)
buflen = len;
return hp;
}
/* END CODE */

View File

@@ -973,15 +973,13 @@ zprimetest(ZVALUE z, long count, ZVALUE skip)
if (ziszero(skip)) {
type = 0;
zbase = _zero_;
}
else if (zisone(skip)) {
} else if (zisone(skip)) {
type = 1;
itoz(2, &zbase);
limit = 1 << 16;
if (!zge16b(z))
limit = ztolong(z);
}
else {
} else {
type = 2;
if (zrel(skip, z) >= 0 || zisneg(skip))
zmod(skip, z, &zbase, 0);
@@ -1082,15 +1080,13 @@ zredcprimetest(ZVALUE z, long count, ZVALUE skip)
if (ziszero(skip)) {
zbase = _zero_;
type = 0;
}
else if (zisone(skip)) {
} else if (zisone(skip)) {
itoz(2, &zbase);
type = 1;
limit = 1 << 16;
if (!zge16b(z))
limit = ztolong(z);
}
else {
} else {
zredcencode(rp, skip, &zbase);
type = 2;
}

View File

@@ -2527,7 +2527,8 @@ random_libcalc_cleanup(void)
static void
zfree_random(ZVALUE z)
{
if (z.v != h_ndefvec && z.v != h_rdefvec && z.v != h_rdefvec_2 &&
if (z.v != NULL &&
z.v != h_ndefvec && z.v != h_rdefvec && z.v != h_rdefvec_2 &&
z.v != h_nvec01 && z.v != h_rvec01 &&
z.v != h_nvec02 && z.v != h_rvec02 &&
z.v != h_nvec03 && z.v != h_rvec03 &&