Compare commits

...

37 Commits

Author SHA1 Message Date
Landon Curt Noll
8d6f83ad91 Release v2.15.0.2
The following are the changes in this release:

    Updated BUGS about MSYS2 on Windows compiling of calc.

    Added more git related checks and sanity checks to chk_tree.

    Added ${FSANITIZE} make variable to Makefile.config to hold
    common Address Sanitizer (ASAN) optins to modern Linux and macOS.
    The Address Sanitizer is NOT enabled not compiled in by default.
    Improved comments in Makefile.local for RHEL9.2 (Linux) and for
    macOS 14.0 that, when uncommented and calc is recompiled (i.e.,
    make clobber all) will enable the Address Sanitizer (ASAN) for calc.

    Fixed memory leaks in the logn, aversin, acoversin, avercos,
    acovercos, ahaversin, ahavercos, ahacovercos, aexsec,
    aexcsc, and acrd.

    Fixed a compile error in zmath.h that impacted legacy 32-bit Big
    Endian machines.  Thanks goes to GitHub user @gromit1811 for their
    pull request.

    Fixed the check for <sys/mount.h> when forming have_sys_mount.h.
    Thanks goes to GitHub user @gromit1811 for their pull request.

    Added "STATIC bool blum_initialized = false" to zrandom.c to improve
    how the code detects if the Blum-Blum-Shub pseudo-random number
    generator is seeded or not, and how to free the state correctly.

    NOTE: There is a very minor memory leak in zrandom.c that will be
    fixed in a later release.
2023-12-08 14:03:07 -08:00
Landon Curt Noll
8dd380a9f7 prep CHANGES for the next release of calc 2023-12-08 13:56:48 -08:00
Landon Curt Noll
fbaff69c92 improve how random seed state is determined
Added "STATIC bool blum_initialized = false" to zrandom.c to improve
how the code detects if the Blum-Blum-Shub pseudo-random number
generator is seeded or not, and how to free the state correctly.

NOTE: There is a very minor memory leak in zrandom.c that will be
fixed in a later release.
2023-12-08 13:51:14 -08:00
Landon Curt Noll
c724227ef9 thank GitHub user @gromit1811 for have_sys_mount.h fix 2023-11-02 17:25:51 -07:00
Landon Curt Noll
3fd64578a6 Merge pull request #132 from gromit1811/fix_have_sys_mount
Actually check for sys/mount.h when forming have_sys_mount.h
2023-11-02 17:24:25 -07:00
Martin Buck
c9c4105ddc Actually check for sys/mount.h when forming have_sys_mount.h
So far, the Makefile checked for sys/param.h instead and that suspiciously
looks like a copy & paste error.

Found by the Debian hurd-i386 build daemon because calc failed to compile
there and it seems to lack sys/mount.h. Not that this would be an extremely
relevant architecture these days, but nevertheless... ;-)
2023-11-02 21:43:10 +01:00
Landon Curt Noll
80b7cd34fe final tweak to the thanks in CHANGES .. promise :-)
We could collapse the last 3+ commits, but
then again why try to cover up the fun!  :-)
2023-11-01 16:17:59 -07:00
Landon Curt Noll
630947d35c improve thanks in CHANGES :-) 2023-11-01 16:15:15 -07:00
Landon Curt Noll
45f62fd7b4 fixed a typo in the previous commit :-) 2023-11-01 16:14:33 -07:00
Landon Curt Noll
8ca980b2bb Thank GitHub user @gromit1811 for zmath.h fix 2023-11-01 16:13:25 -07:00
Landon Curt Noll
2ace631d00 Merge branch 'master' of github.com:lcn2/calc 2023-11-01 16:05:56 -07:00
Landon Curt Noll
41d339c60e updated trigonometric function list in help/unexpected 2023-11-01 16:04:45 -07:00
Landon Curt Noll
cc3bb98fa0 Merge pull request #131 from gromit1811/fix-fposval-build-failure 2023-11-01 15:58:53 -07:00
Martin Buck
2b506a74e7 Fix file.c build failure on 32 bit big endian machines
On ancient 32 bit big endian machines (e.g. MIPS) file.c fails to build
when FILEPOS is a struct and not a scalar. This happens because the
SWAP_HALF_IN_FILEPOS macro essentially expands to a simple assignment in
this case but the types are incompatile (HALF and FILEPOS).

Detailed compile error (this is from an older version so line numbers might
be wrong but the error is the same):

gcc  -DCALC_SRC -DCUSTOM -Wall  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security   -O3 -g3 -Wno-error=long-long -Wno-long-long -c file.c
In file included from qmath.h:32,
                 from cmath.h:32,
                 from value.h:33,
                 from calc.h:33,
                 from file.c:39:
file.c: In function 'filepos2z':
zmath.h:85:46: error: incompatible types when assigning to type 'HALF' {aka 'long unsigned int'} from type 'FILEPOS' {aka 'struct _G_fpos_t'}
 #define SWAP_HALF_IN_B32(dest, src) (*(dest) = *(src))
                                              ^
fposval.h:15:42: note: in expansion of macro 'SWAP_HALF_IN_B32'
 #define SWAP_HALF_IN_FILEPOS(dest, src)  SWAP_HALF_IN_B32(dest, src)
                                          ^~~~~~~~~~~~~~~~
file.c:1370:2: note: in expansion of macro 'SWAP_HALF_IN_FILEPOS'
  SWAP_HALF_IN_FILEPOS(ret.v, &pos);
  ^~~~~~~~~~~~~~~~~~~~

Fix this by adding suitable casts to the definition of SWAP_HALF_IN_FILEPOS
on big endian machines. Strictly speaking, the casts only seem to be
necessary when using SWAP_HALF_IN_B32, but they can't hurt in the other
cases either.
2023-11-01 21:30:43 +01:00
Landon Curt Noll
826d2d8175 Merge pull request #129 from gromit1811/man-wrap-long-paths 2023-10-17 15:53:14 -07:00
Landon Curt Noll
af8ffb3098 Merge pull request #128 from gromit1811/master 2023-10-17 15:11:31 -07:00
Martin Buck
71dd30c4c6 Allow word-wrapping in long path names in man page 2023-10-18 00:09:37 +02:00
Martin Buck
8ca96a8c29 Fix minor man page spelling errors 2023-10-17 23:41:02 +02:00
Landon Curt Noll
0bba80c92b Merge pull request #118 from planet36/help-typos
Fix minor typos in help docs
2023-10-10 07:08:34 -07:00
Steven Ward
c1882e2ea0 Use full name of function to match help file 2023-10-09 21:29:56 -04:00
Steven Ward
79964338d1 Fix minor typos 2023-10-09 21:29:47 -04:00
Steven Ward
d809ce5cf0 Use null() instead of nul() 2023-10-09 21:24:47 -04:00
Steven Ward
daac7b35af ctime() does not remove the trailing newline 2023-10-09 21:23:53 -04:00
Steven Ward
40d6e22318 s/windowz/Windows/ 2023-10-09 21:23:36 -04:00
Landon Curt Noll
ab2038ecbc fix more memory leaks
Fixed more memory leaks in the aversin, acoversin, avercos,
acovercos, ahaversin, ahavercos, ahacovercos, aexsec,
aexcsc, and acrd.
2023-10-06 23:54:55 -07:00
Landon Curt Noll
0b57d6b605 fix memory leak in the logn builtin function 2023-10-06 23:27:42 -07:00
Landon Curt Noll
01f0605055 improve chk_tree and trailblank
The chk_tree will check for files in distlist that
would otherwise be ignored by trailblank or that
are used, by convention, as tempory / test files.

Fixed a shellcheck nit in trailblank.
2023-10-06 22:25:00 -07:00
Landon Curt Noll
0e6016f429 improve Address Sanitizer (ASAN) support and chk_tree
Updated BUGS about MSYS2 on Windows compiling of calc.

    Added more git related checks and sanity checks to chk_tree.

    Added ${FSANITIZE} make variable to Makefile.config to hold
    common Address Sanitizer (ASAN) optins to modern Linux and macOS.
    The Address Sanitizer is NOT enabled not compiled in by default.
    Improved comments in Makefile.local for RHEL9.2 (Linux) and for
    macOS 14.0 that, when uncommented and calc is recompiled (i.e.,
    make clobber all) will enable the Address Sanitizer (ASAN) for calc.
2023-10-06 21:59:06 -07:00
Landon Curt Noll
2d2e1c5894 change make prep to report on chk_tree failures
Before, make prep would show but not object to chk_tree failures.
Now, if all except chk_tree is OK, make prep will report:

    almost satifactory except for chk_tree
2023-10-06 18:39:04 -07:00
Landon Curt Noll
50ba5f9a3e improve and update FSANITIZE comments in Makefile.local 2023-10-06 18:38:06 -07:00
Landon Curt Noll
850cdbef1d fix chk_tree ahead / behind direction 2023-10-06 18:05:59 -07:00
Landon Curt Noll
21cedfcae4 improve branch check for chk_tree 2023-10-06 18:04:05 -07:00
Landon Curt Noll
4fa137a638 update BUGS about MSYS2 and Windows success 2023-10-06 18:00:06 -07:00
Landon Curt Noll
6ebe707670 fix git branch checks 2023-10-06 17:55:12 -07:00
Landon Curt Noll
885db22315 add git branch checks to chk_tree 2023-10-06 17:52:30 -07:00
Landon Curt Noll
06a9997da7 fix git diff and improve git diff detection 2023-10-06 17:38:01 -07:00
Landon Curt Noll
fae4b8e81b add git checks for staged and unstaged changes 2023-10-06 17:31:37 -07:00
21 changed files with 479 additions and 226 deletions

4
BUGS
View File

@@ -101,7 +101,9 @@ Known bugs in calc:
The output of the alg_config.cal resource file is bogus.
We would welcome a replacement for this code.
Calc may not compile natively under Windows 11. See README.WINDOWS.
Calc may not compile natively under Windows 11, however with
MSYS2 Software Distribution (a fork of Cygwin) people compile
calc under Windiws just fine. See README.WINDOWS.
We are sure some more bugs exist. When you find them, please let
us know! See the above for details on how to report and were to

34
CHANGES
View File

@@ -1,3 +1,35 @@
The following are the changes from calc version 2.15.0.1 to 2.15.0.2:
Updated BUGS about MSYS2 on Windows compiling of calc.
Added more git related checks and sanity checks to chk_tree.
Added ${FSANITIZE} make variable to Makefile.config to hold
common Address Sanitizer (ASAN) optins to modern Linux and macOS.
The Address Sanitizer is NOT enabled not compiled in by default.
Improved comments in Makefile.local for RHEL9.2 (Linux) and for
macOS 14.0 that, when uncommented and calc is recompiled (i.e.,
make clobber all) will enable the Address Sanitizer (ASAN) for calc.
Fixed memory leaks in the logn, aversin, acoversin, avercos,
acovercos, ahaversin, ahavercos, ahacovercos, aexsec,
aexcsc, and acrd.
Fixed a compile error in zmath.h that impacted legacy 32-bit Big
Endian machines. Thanks goes to GitHub user @gromit1811 for their
pull request.
Fixed the check for <sys/mount.h> when forming have_sys_mount.h.
Thanks goes to GitHub user @gromit1811 for their pull request.
Added "STATIC bool blum_initialized = false" to zrandom.c to improve
how the code detects if the Blum-Blum-Shub pseudo-random number
generator is seeded or not, and how to free the state correctly.
NOTE: There is a very minor memory leak in zrandom.c that will be
fixed in a later release.
The following are the changes from calc version 2.14.3.5 to 2.15.0.1:
The tarball for calc version 2.15.0.0 was missing version.h.
@@ -4228,7 +4260,7 @@ The following are the changes from calc version 2.11.5t0 to 2.11.5t1.1:
Fixed calc path in help/script.
Added read-only parameter, config("windows") to indicate if the system
is MS windowz WIN32 like system.
is MS Windows WIN32 like system.
Configuration values that used to return "true" or "false" now return
1 (a true value) or 0 (a false value). Thus one can do:

View File

@@ -510,6 +510,8 @@ libcalc${LIB_EXT_VER}: libcalc${LIB_EXT_VERSION}
#
###
# Note: The :\(...-sed pattern below allows word wrapping at the separators
# of long path names (typically CALCPATH and CALCRC).
calc.1: calc.man ${MK_SET}
${RM} -f $@
${Q} echo forming calc.1 from calc.man
@@ -523,7 +525,8 @@ calc.1: calc.man ${MK_SET}
-e 's,$${CUSTOMINCDIR},${CUSTOMINCDIR},g' \
-e 's,$${HELPDIR},${HELPDIR},g' \
-e 's,$${CUSTOMHELPDIR},${CUSTOMHELPDIR},g' \
-e 's,$${CALCRC},${CALCRC},g' < calc.man > calc.1
-e 's,$${CALCRC},${CALCRC},g' \
-e 's,:\([/.~]\),:\\:\1,g' < calc.man > calc.1
${Q} echo calc.1 formed
calc.usage: calc.1 ${MK_SET}
@@ -1821,7 +1824,7 @@ have_sys_mount.h: ${MK_SET}
echo '#define HAVE_SYS_MOUNT_H /* yes */' >> $@; \
elif [ X"${HAVE_SYS_MOUNT_H}" = X"NO" ]; then \
echo '#undef HAVE_SYS_MOUNT_H /* no */' >> $@; \
elif echo '#include <sys/param.h>' | ${CC} -E - ${S}; then \
elif echo '#include <sys/mount.h>' | ${CC} -E - ${S}; then \
echo '#define HAVE_SYS_MOUNT_H /* yes */' >> $@; \
else \
echo '#undef HAVE_SYS_MOUNT_H /* no */' >> $@; \
@@ -3215,19 +3218,17 @@ prep:
${Q}echo
${Q}echo '=-=-=-=-=-= end of ${UPDATE_VER} =-=-=-=-=-='
${Q}echo
${Q}echo '=-=-=-=-=-= start of chk_tree pass #1 =-=-=-=-=-='
${Q}echo
-./chk_tree
${Q}echo
${Q}echo '=-=-=-=-=-= end of chk_tree pass #1 =-=-=-=-=-='
${Q}echo
${Q}echo '=-=-=-=-=-= start of ${MAKE} chk =-=-=-=-=-='
${Q}echo
${MAKE} -s chk
${Q}echo
${Q}echo '=-=-=-=-=-= end of ${MAKE} chk =-=-=-=-=-='
${Q}echo
${Q}echo All is OK
@${Q}if ! ./chk_tree >/dev/null 2>&1; then \
echo almost satifactory except for chk_tree; \
else \
echo All is OK; \
fi
${Q}echo
run:

View File

@@ -1276,7 +1276,7 @@ EXT=
# The calc version in the form of x.y.z.w
#
VERSION= 2.15.0.1
VERSION= 2.15.0.2
# The calc major version in the form of x.y.z
#
@@ -1382,3 +1382,34 @@ endif # ($(ALLOW_CUSTOM),-DCUSTOM)
# intermediate and final calc and calc related programs
#
COMMON_LDFLAGS= ${EXTRA_LDFLAGS}
# Common Address Sanitizer (ASAN)
#
# For more info see: https://github.com/google/sanitizers/wiki/AddressSanitizer
# See also: https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early
#
# The following Address Sanitizer (ASAN) are common to both REHL9.2 (Linux) and macOS 14.0.
#
# By default, the Address Sanitizer is NOT enabled, not compiled into calc.
# To enable the Address Sanitizer, uncomment the appropriate lines in Makefile.local !!!
#
FSANITIZE:= -Wno-invalid-command-line-argument
FSANITIZE+= -fsanitize=address
FSANITIZE+= -fsanitize=alignment
FSANITIZE+= -fsanitize=bool
FSANITIZE+= -fsanitize=enum
FSANITIZE+= -fsanitize=vptr
FSANITIZE+= -fsanitize=integer-divide-by-zero
FSANITIZE+= -fsanitize=float-divide-by-zero
FSANITIZE+= -fsanitize=float-cast-overflow
FSANITIZE+= -fsanitize=nonnull-attribute
FSANITIZE+= -fsanitize=returns-nonnull-attribute
FSANITIZE+= -fsanitize=null
FSANITIZE+= -fsanitize=object-size
FSANITIZE+= -fsanitize=shift
FSANITIZE+= -fsanitize=signed-integer-overflow
FSANITIZE+= -fsanitize=undefined
FSANITIZE+= -fsanitize=unreachable
FSANITIZE+= -fsanitize=vla-bound
FSANITIZE+= -fno-omit-frame-pointer
FSANITIZE+= -fno-common

View File

@@ -50,75 +50,51 @@
###################################################################
####
#
# Force calc to install under /usr/local
#
# BINDIR:= /usr/local/bin
# LIBDIR:= /usr/local/lib
# CALC_SHAREDIR:= /usr/local/share/calc
# CALC_INCDIR:= /usr/local/include/calc
#
# PREFIX:= /usr/local
# BINDIR:= ${PREFIX}/bin
# LIBDIR:= ${PREFIX}/lib
# CALC_SHAREDIR:= ${PREFIX}/share/calc
# CALC_INCDIR:= ${PREFIX}/include/calc
####
####
# RHEL Diagnosing memory, thread, and crash issues:
#
# For more info see: https://github.com/google/sanitizers/wiki/AddressSanitizer
# macOS Address Sanitizer (ASAN)
#
# This comment block was tested under:
#
# RHEL9 gcc version 11.3.1 20221121 (Red Hat 11.3.1-4) (GCC)
# macOS 14.0 with Apple clang version 15.0.0 (clang-1500.0.40.1) for arm64
#
# with:
# See the FSANITIZE comment block in Makefile.config for common FSANITIZE values and more info.
#
# libasan-11.3.1-4.3.el9.x86_64 libubsan-11.3.1-4.3.el9.x86_64
# To use the Address Sanitizer, uncomment this set set of lines and recompile (make clobber all):
#
# NOTE: With the above version, these are NOT supported:
#
# UNSUPPORTED_FSANITIZE:= -fsanitize=nullability-arg -fsanitize=nullability-assign
#
# Uncomment these lines:
#
# FSANITIZE:= -fsanitize=undefined -fsanitize=address -fsanitize=bool -fsanitize=bounds
# FSANITIZE+= -fsanitize=enum -fsanitize=vptr -fsanitize=integer-divide-by-zero
# FSANITIZE+= -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow
# FSANITIZE+= -fsanitize=nonnull-attribute -fsanitize=returns-nonnull-attribute
# FSANITIZE+= -fsanitize=null -fsanitize=shift -fsanitize=signed-integer-overflow
# FSANITIZE+= -fsanitize=unreachable -fsanitize=vla-bound
# CFLAGS+= -Wno-invalid-command-line-argument ${FSANITIZE} -fno-omit-frame-pointer
# LDFLAGS+= -Wno-invalid-command-line-argument ${FSANITIZE} -fno-omit-frame-pointer
# CALC_ENV+= ASAN_OPTIONS=detect_stack_use_after_return=1
# DEBUG:= -O0 -g
####
####
# macOS Diagnosing memory, thread, and crash issues:
#
# For more info see: https://github.com/google/sanitizers/wiki/AddressSanitizer
#
# This comment block was tested under:
#
# macOS 13.5 with clang version 14.0.3 (clang-1403.0.22.14.1)
#
# For more info for clang to Diagnosing memory, thread, and crash issues early, see:
#
# https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early
#
# NOTE: With the above version, these are NOT supported:
#
# UNSUPPORTED_FSANITIZE:= -fsanitize-nullability-return
#
# Uncomment these lines:
#
# FSANITIZE:= -fsanitize=undefined -fsanitize=address -fsanitize=bool -fsanitize=bounds
# FSANITIZE+= -fsanitize=enum -fsanitize=vptr -fsanitize=integer-divide-by-zero
# FSANITIZE+= -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow
# FSANITIZE+= -fsanitize=nonnull-attribute -fsanitize=nullability-arg
# FSANITIZE+= -fsanitize=nullability-assign -fsanitize=returns-nonnull-attribute
# FSANITIZE+= -fsanitize=null -fsanitize=object-size -fsanitize=shift
# FSANITIZE+= -fsanitize=signed-integer-overflow -fsanitize=unreachable -fsanitize=vla-bound
# CFLAGS+= -Wno-invalid-command-line-argument ${FSANITIZE} -fno-omit-frame-pointer
# LDFLAGS+= -Wno-invalid-command-line-argument ${FSANITIZE} -fno-omit-frame-pointer
# CALC_ENV+= ASAN_OPTIONS=detect_stack_use_after_return=1
# FSANITIZE+= -fsanitize=nullability-arg
# FSANITIZE+= -fsanitize=nullability-assign
# FSANITIZE+= -fsanitize=nullability-return
# CFLAGS+= ${FSANITIZE}
# LDFLAGS+= ${FSANITIZE}
# DEBUG:= -O0 -g3
####
####
# RHEL (Linux) Address Sanitizer (ASAN)
#
# This comment block was tested under:
#
# RHEL9.2 with clang version 15.0.7 (Red Hat 15.0.7-2.el9) for x86_64
#
# with these RPMs installed:
#
# libasan-11.3.1-4.3.el9.x86_64 libubsan-11.3.1-4.3.el9.x86_64
#
# See the FSANITIZE comment block in Makefile.config for common FSANITIZE values and more info.
#
# To use the Address Sanitizer, uncomment this set set of lines and recompile (make clobber all):
#
# FSANITIZE+= -fsanitize=bounds
# CFLAGS+= ${FSANITIZE}
# LDFLAGS+= ${FSANITIZE}
# DEBUG:= -O0 -g3
###

View File

@@ -501,7 +501,7 @@ version number and exit.
.TP
.B \-\-
The double dash indicates to calc that no more option follow.
The double dash indicates to calc that no more options follow.
Thus calc will ignore a later argument on the command line
even if it starts with a dash.
This is useful when entering negative values on the command line as in:
@@ -543,7 +543,7 @@ will not evaluate any
arguments but instead make them available
as strings to the argv() builtin function.
Sufficiently simple commands with no no characters like
Sufficiently simple commands with no characters like
parentheses, brackets, semicolons, '*', which have special
interpretations in UNIX shells may be entered, possibly with
spaces, until the terminating newline.
@@ -804,7 +804,7 @@ the rest of the file will be processed in
Note that
.B \-s
.B \-f
must at the end of the initial ``#!'' line.
must be at the end of the initial ``#!'' line.
Any other optional
.B "optional_other_flags"
must come before
@@ -973,7 +973,7 @@ Before a variable is assigned a value it has the value of zero.
.PP
The scope of a variable may be global, local to a file, or local to a
procedure.
Values may be grouped together in a matrix, or into a
Values may be grouped together in a matrix, or into
a list that permits stack and queue style operations.
.PP
For more information use the following

119
chk_tree
View File

@@ -46,6 +46,11 @@ fi
#
declare -a DISTDIR
mapfile -t DISTDIR < <(make -s distdir | grep -v '^make\[[0-9]*\]: ' | sort -u)
if [[ ${#DISTDIR[@]} -le 0 ]]; then
echo "$0: ERROR: distdir is empty" 1>&2
EXIT_CODE=11
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
# collect directories
#
@@ -58,6 +63,11 @@ mapfile -t FINDDIR < <(find . -type d \
! -path './.git/*' ! -name .git \
! -path './.github/*' ! -name .github | \
sed -e 's/^\.\///' | sort -u)
if [[ ${#FINDDIR[@]} -le 0 ]]; then
echo "$0: ERROR: find dir is empty" 1>&2
EXIT_CODE=12
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
# compare DISTDIR and FINDDIR
#
@@ -81,7 +91,7 @@ if [[ ${#DIFF_DISTDIR_FINDDIR[@]} -ne 0 ]]; then
if [[ ${#ONLY_DISTDIR[@]} -ne 0 ]]; then
echo "$0: ERROR: found only in distdir: ${ONLY_DISTDIR[*]}" 1>&2
fi
EXIT_CODE=11
EXIT_CODE=13
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
@@ -91,7 +101,7 @@ make distlist >/dev/null 2>&1
status="$?"
if [[ $status -ne 0 ]]; then
echo "$0: ERROR: make distlist exit code: $status" 1>&2
EXIT_CODE=12
EXIT_CODE=14
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
@@ -99,6 +109,11 @@ fi
#
declare -a DISTLIST
mapfile -t DISTLIST < <(make -s distlist | grep -v '^make\[[0-9]*\]: ' | sort -u)
if [[ ${#DISTLIST[@]} -le 0 ]]; then
echo "$0: ERROR: distlist is empty" 1>&2
EXIT_CODE=15
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
declare -A DISTLIST_A
for i in "${DISTLIST[@]}"; do
DISTLIST_A["$i"]="$i"
@@ -116,6 +131,11 @@ if [[ -d .git ]]; then
mapfile -t GITLS < <(git ls |
grep -v -E '^\.github/|^\.gitignore$|^CODE_OF_CONDUCT\.md$|^CONTRIBUTING\.md$|^SECURITY\.md$' |
sort -u)
if [[ ${#GITLS[@]} -le 0 ]]; then
echo "$0: ERROR: git ls is empty" 1>&2
EXIT_CODE=16
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
# compare DISTLIST and GITLS
#
@@ -139,7 +159,58 @@ if [[ -d .git ]]; then
if [[ ${#ONLY_DISTLIST[@]} -ne 0 ]]; then
echo "$0: ERROR: found only in distlist: ${ONLY_DISTLIST[*]}" 1>&2
fi
EXIT_CODE=13
EXIT_CODE=17
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
# verify that there are no staged uncommitted changes under git
#
GIT_STATUS=$(git status --untracked-files=no --porcelain 2>&1)
if [[ -n $GIT_STATUS ]] || ! git diff --cached --quiet --exit-code; then
echo "$0: ERROR: there are staged uncommitted changes" 1>&2
git status --short
EXIT_CODE=18
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
# verify that there are no uncommitted changes under git
#
if ! git diff --quiet --exit-code; then
echo "$0: ERROR: there are unstaged changes" 1>&2
git status --untracked-files=no --porcelain --short
EXIT_CODE=19
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
# verify that master branch is not ahead of 'origin/master'
#
GIT_MASTER=$(git rev-list --count master)
GIT_ORIGIN_MASTER=$(git rev-list --count origin/master)
if [[ $GIT_MASTER -gt $GIT_ORIGIN_MASTER ]]; then
echo "$0: ERROR: master branch is behind of origin/master" 1>&2
git status master
EXIT_CODE=20
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
elif [[ $GIT_MASTER -lt $GIT_ORIGIN_MASTER ]]; then
echo "$0: ERROR: master branch is ahead of origin/master" 1>&2
git status master
EXIT_CODE=21
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
# verify that branch is not ahead of 'origin/HEAD'
#
GIT_HEAD=$(git rev-list --count HEAD)
GIT_ORIGIN_HEAD=$(git rev-list --count origin/HEAD)
if [[ $GIT_HEAD -gt $GIT_ORIGIN_HEAD ]]; then
echo "$0: ERROR: HEAD is behind of origin/HEAD" 1>&2
git status HEAD
EXIT_CODE=22
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
elif [[ $GIT_HEAD -lt $GIT_ORIGIN_HEAD ]]; then
echo "$0: ERROR: HEAD is ahead of origin/HEAD" 1>&2
git status HEAD
EXIT_CODE=23
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
fi
@@ -148,6 +219,11 @@ fi
#
declare -a BUILDLIST
mapfile -t BUILDLIST < <(make -s buildlist | grep -v '^make\[[0-9]*\]: ' | sort -u)
if [[ ${#BUILDLIST[@]} -le 0 ]]; then
echo "$0: ERROR: buildlist is empty" 1>&2
EXIT_CODE=24
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
declare -A BUILDLIST_A
for i in "${BUILDLIST[@]}"; do
BUILDLIST_A["$i"]="$i"
@@ -173,7 +249,7 @@ if [[ ${#DISTLIST_ALSO_IN_BUILDLIST[@]} -ne 0 ]]; then
#
echo "$0: ERROR: distlist files found in buildlist" 1>&2
echo "$0: ERROR: distlist files found in buildlist: ${DISTLIST_ALSO_IN_BUILDLIST[*]}" 1>&2
EXIT_CODE=14
EXIT_CODE=25
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
@@ -184,6 +260,9 @@ fi
# We ignore .*.swp files as they are a result of vim sessions.
# We ignore *.out files as they are used to collect information.
# We ignore single letter files as they are used for temporary files.
# We ignore files containing the any of the following in any letter case:
#
# foo bar baz curds whey rmme
#
declare -a FINDFILE
mapfile -t FINDFILE < <(find . -type f \
@@ -191,8 +270,15 @@ mapfile -t FINDFILE < <(find . -type f \
! -path './.git/*' ! -name .git \
! -path './.github/*' ! -name .github \
! -name 'CODE_OF_CONDUCT.md' ! -name 'CONTRIBUTING.md' ! -name '.gitignore' ! -name 'SECURITY.md' \
! -name '*.swp' ! -name '*.out' ! -name '?' |
! -name '*.swp' ! -name '?' ! -iname '*.out*' \
! -iname '*foo*' ! -iname '*bar*' ! -iname '*baz*' \
! -iname '*curds*' ! -iname '*whey*' ! -iname '*rmmee' -print |
sed -e 's/^\.\///' | sort -u)
if [[ ${#FINDFILE[@]} -le 0 ]]; then
echo "$0: ERROR: find file is empty" 1>&2
EXIT_CODE=26
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
# look for something in FINDFILE that in neither DISTLIST nor BUILDLIST
#
@@ -231,7 +317,28 @@ if [[ ${#UNKNOWN_FILE[@]} -ne 0 ]]; then
#
echo "$0: ERROR: files that are neither built nor distlist are found" 1>&2
echo "$0: ERROR: distlist files found in buildlist: ${UNKNOWN_FILE[*]}" 1>&2
EXIT_CODE=15
EXIT_CODE=27
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi
# Look for a find in distlist that would otherwise be ignored
#
# We ignore for trailblank and FINDFILE, filenames with a single letter, and files
# that end in .out, and files containing the any of the following
# in any letter case:
#
# foo bar baz curds whey rmme
#
# So we will object is any distlist file is one of these ignored filenames.
#
INVALID_DISTLIST=$(printf '%s\n' "${DISTLIST[@]}" | \
tr '[:upper:]' '[:lower:]' | \
sed -n -e '/^.$/p' -e '/.*foo.*/p' -e '/.*bar.*/p' -e '/.*baz.*/p' \
-e '/.*curds.*/p' -e '/.*whey.*/p' -e '/.*rmme.*/p' |
tr '\n' ' ')
if [[ -n $INVALID_DISTLIST ]]; then
echo "$0: ERROR: distlist contains invalid filename(s): $INVALID_DISTLIST" 1>&2
EXIT_CODE=28
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
fi

View File

@@ -114,15 +114,20 @@ main(int UNUSED(argc), char **argv)
/*
* Big Endian
*/
/*
* Use casts to (HALF *) because SWAP_HALF_IN_B* might expand to
* a simple assignment and SWAP_HALF_IN_FILEPOS might get a
* (HALF *) and a (FILEPOS *) which are not assignment-compatible.
*/
if (fileposlen == 64) {
printf("#define SWAP_HALF_IN_FILEPOS(dest, src) \\\n"
"\tSWAP_HALF_IN_B64(dest, src)\n");
"\tSWAP_HALF_IN_B64((HALF *)dest, (HALF *)src)\n");
} else if (fileposlen == 32) {
printf("#define SWAP_HALF_IN_FILEPOS(dest, src) \\\n"
"\tSWAP_HALF_IN_B32(dest, src)\n");
"\tSWAP_HALF_IN_B32((HALF *)dest, (HALF *)src)\n");
} else if (fileposlen%BASEB == 0) {
printf("#define SWAP_HALF_IN_FILEPOS(dest, src) \\\n"
"\tswap_HALFs(dest, src, %d)\n",
"\tswap_HALFs((HALF *)dest, (HALF *)src, %d)\n",
fileposlen/BASEB);
} else {
fprintf(stderr, "%s: unexpected BIG_ENDIAN FILEPOS bit size: %d\n",

234
func.c
View File

@@ -2479,6 +2479,7 @@ f_logn(int count, VALUE **vals)
ln_of_x_is_complex = true;
}
} else {
ln_x_c = NULL; /* avoid ln_x_c may be uninitialized warning later on */
ln_x_r = qln(vals[0]->v_num, err);
if (ln_x_r == NULL) {
return error_value(E_LOGN_3);
@@ -2512,6 +2513,11 @@ f_logn(int count, VALUE **vals)
switch (vals[1]->v_type) {
case V_NUM:
if (qiszero(vals[1]->v_num)) {
if (ln_of_x_is_complex == true) {
comfree(ln_x_c);
} else {
qfree(ln_x_r);
}
return error_value(E_LOGN_4);
}
if (qisneg(vals[1]->v_num)) {
@@ -2520,10 +2526,20 @@ f_logn(int count, VALUE **vals)
ctmp.links = 1;
ln_n_c = c_ln(&ctmp, err);
if (ln_n_c == NULL) {
if (ln_of_x_is_complex == true) {
comfree(ln_x_c);
} else {
qfree(ln_x_r);
}
return error_value(E_LOGN_4);
}
if (ciszero(ln_n_c)) {
comfree(ln_n_c);
if (ln_of_x_is_complex == true) {
comfree(ln_x_c);
} else {
qfree(ln_x_r);
}
return error_value(E_LOGN_4);
}
if (cisreal(ln_n_c)) {
@@ -2534,24 +2550,49 @@ f_logn(int count, VALUE **vals)
} else {
ln_n_r = qln(vals[1]->v_num, err);
if (ln_n_r == NULL) {
if (ln_of_x_is_complex == true) {
comfree(ln_x_c);
} else {
qfree(ln_x_r);
}
return error_value(E_LOGN_4);
}
if (qiszero(ln_n_r)) {
qfree(ln_n_r);
if (ln_of_x_is_complex == true) {
comfree(ln_x_c);
} else {
qfree(ln_x_r);
}
return error_value(E_LOGN_4);
}
}
break;
case V_COM:
if (ciszero(vals[1]->v_com)) {
if (ln_of_x_is_complex == true) {
comfree(ln_x_c);
} else {
qfree(ln_x_r);
}
return error_value(E_LOGN_4);
}
ln_n_c = c_ln(vals[1]->v_com, err);
if (ln_n_c == NULL) {
if (ln_of_x_is_complex == true) {
comfree(ln_x_c);
} else {
qfree(ln_x_r);
}
return error_value(E_LOGN_4);
}
if (ciszero(ln_n_c)) {
comfree(ln_n_c);
if (ln_of_x_is_complex == true) {
comfree(ln_x_c);
} else {
qfree(ln_x_r);
}
return error_value(E_LOGN_4);
}
if (cisreal(ln_n_c)) {
@@ -2561,6 +2602,11 @@ f_logn(int count, VALUE **vals)
}
break;
default:
if (ln_of_x_is_complex == true) {
comfree(ln_x_c);
} else {
qfree(ln_x_r);
}
return error_value(E_LOGN_5);
}
@@ -2574,6 +2620,8 @@ f_logn(int count, VALUE **vals)
* case: ln(x) is COMPLEX, ln(n) is COMPLEX
*/
p_cval = c_div(ln_x_c, ln_n_c);
comfree(ln_x_c);
comfree(ln_n_c);
if (p_cval == NULL) {
return error_value(E_LOGN_3);
}
@@ -2594,6 +2642,8 @@ f_logn(int count, VALUE **vals)
* case: ln(x) is COMPLEX, ln(n) is NUMBER
*/
p_cval = c_divq(ln_x_c, ln_n_r);
comfree(ln_x_c);
qfree(ln_n_r);
if (p_cval == NULL) {
return error_value(E_LOGN_3);
}
@@ -2620,6 +2670,8 @@ f_logn(int count, VALUE **vals)
ctmp.imag = qlink(&_qzero_);
ctmp.links = 1;
p_cval = c_div(&ctmp, ln_n_c);
comfree(&ctmp);
comfree(ln_n_c);
if (p_cval == NULL) {
return error_value(E_LOGN_3);
}
@@ -2640,6 +2692,8 @@ f_logn(int count, VALUE **vals)
* case: ln(x) is NUMBER, ln(n) is NUMBER
*/
result.v_num = qqdiv(ln_x_r, ln_n_r);
qfree(ln_x_r);
qfree(ln_n_r);
if (result.v_com == NULL) {
return error_value(E_LOGN_3);
}
@@ -10900,7 +10954,6 @@ f_versin(int count, VALUE **vals)
S_FUNC VALUE
f_aversin(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -10924,11 +10977,10 @@ f_aversin(int count, VALUE **vals)
/*
* compute inverse versed trigonometric sine to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* try to compute result using real trig function */
result.v_num = qaversin_or_NULL(arg1.v_num, eps);
result.v_num = qaversin_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -10941,17 +10993,17 @@ f_aversin(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_aversin(arg1.v_com, eps);
c = c_aversin(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_AVERSIN_3);
}
@@ -10966,7 +11018,7 @@ f_aversin(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -11040,7 +11092,6 @@ f_coversin(int count, VALUE **vals)
S_FUNC VALUE
f_acoversin(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -11064,11 +11115,10 @@ f_acoversin(int count, VALUE **vals)
/*
* compute inverse coversed trigonometric sine to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* try to compute result using real trig function */
result.v_num = qacoversin_or_NULL(arg1.v_num, eps);
result.v_num = qacoversin_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -11081,17 +11131,17 @@ f_acoversin(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_acoversin(arg1.v_com, eps);
c = c_acoversin(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_ACOVERSIN_3);
}
@@ -11106,7 +11156,7 @@ f_acoversin(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -11180,7 +11230,6 @@ f_vercos(int count, VALUE **vals)
S_FUNC VALUE
f_avercos(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -11204,11 +11253,10 @@ f_avercos(int count, VALUE **vals)
/*
* compute inverse versed trigonometric cosine to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* try to compute result using real trig function */
result.v_num = qavercos_or_NULL(arg1.v_num, eps);
result.v_num = qavercos_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -11221,17 +11269,17 @@ f_avercos(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_avercos(arg1.v_com, eps);
c = c_avercos(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_AVERCOS_3);
}
@@ -11246,7 +11294,7 @@ f_avercos(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -11320,7 +11368,6 @@ f_covercos(int count, VALUE **vals)
S_FUNC VALUE
f_acovercos(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -11344,11 +11391,10 @@ f_acovercos(int count, VALUE **vals)
/*
* compute inverse coversed trigonometric cosine to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* try to compute result using real trig function */
result.v_num = qacovercos_or_NULL(arg1.v_num, eps);
result.v_num = qacovercos_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -11361,17 +11407,17 @@ f_acovercos(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_acovercos(arg1.v_com, eps);
c = c_acovercos(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_ACOVERCOS_3);
}
@@ -11386,7 +11432,7 @@ f_acovercos(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -11460,7 +11506,6 @@ f_haversin(int count, VALUE **vals)
S_FUNC VALUE
f_ahaversin(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -11484,11 +11529,10 @@ f_ahaversin(int count, VALUE **vals)
/*
* compute inverse half versed trigonometric sine to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* try to compute result using real trig function */
result.v_num = qahaversin_or_NULL(arg1.v_num, eps);
result.v_num = qahaversin_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -11501,17 +11545,17 @@ f_ahaversin(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_ahaversin(arg1.v_com, eps);
c = c_ahaversin(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_AHAVERSIN_3);
}
@@ -11526,7 +11570,7 @@ f_ahaversin(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -11600,7 +11644,6 @@ f_hacoversin(int count, VALUE **vals)
S_FUNC VALUE
f_ahacoversin(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -11624,11 +11667,10 @@ f_ahacoversin(int count, VALUE **vals)
/*
* compute inverse half coversed trigonometric sine to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* try to compute result using real trig function */
result.v_num = qahacoversin_or_NULL(arg1.v_num, eps);
result.v_num = qahacoversin_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -11641,17 +11683,17 @@ f_ahacoversin(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_ahacoversin(arg1.v_com, eps);
c = c_ahacoversin(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_AHACOVERSIN_3);
}
@@ -11666,7 +11708,7 @@ f_ahacoversin(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -11740,7 +11782,6 @@ f_havercos(int count, VALUE **vals)
S_FUNC VALUE
f_ahavercos(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -11764,11 +11805,10 @@ f_ahavercos(int count, VALUE **vals)
/*
* compute inverse half versed trigonometric cosine to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* try to compute result using real trig function */
result.v_num = qahavercos_or_NULL(arg1.v_num, eps);
result.v_num = qahavercos_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -11781,17 +11821,17 @@ f_ahavercos(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_ahavercos(arg1.v_com, eps);
c = c_ahavercos(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_AHAVERCOS_3);
}
@@ -11806,7 +11846,7 @@ f_ahavercos(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -11880,7 +11920,6 @@ f_hacovercos(int count, VALUE **vals)
S_FUNC VALUE
f_ahacovercos(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -11904,11 +11943,10 @@ f_ahacovercos(int count, VALUE **vals)
/*
* compute inverse half coversed trigonometric cosine to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* try to compute result using real trig function */
result.v_num = qahacovercos_or_NULL(arg1.v_num, eps);
result.v_num = qahacovercos_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -11921,17 +11959,17 @@ f_ahacovercos(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_ahacovercos(arg1.v_com, eps);
c = c_ahacovercos(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_AHACOVERCOS_3);
}
@@ -11946,7 +11984,7 @@ f_ahacovercos(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -12016,7 +12054,6 @@ f_exsec(int count, VALUE **vals)
S_FUNC VALUE
f_aexsec(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -12040,16 +12077,15 @@ f_aexsec(int count, VALUE **vals)
/*
* compute inverse exterior trigonometric secant to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* firewall */
if (qisnegone(arg1.v_num)) {
if (qisnegone(vals[0]->v_num)) {
return error_value(E_AEXSEC_3);
}
/* try to compute result using real trig function */
result.v_num = qaexsec_or_NULL(arg1.v_num, eps);
result.v_num = qaexsec_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -12062,17 +12098,17 @@ f_aexsec(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_aexsec(arg1.v_com, eps);
c = c_aexsec(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_AEXSEC_3);
}
@@ -12087,7 +12123,7 @@ f_aexsec(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -12163,7 +12199,6 @@ f_excsc(int count, VALUE **vals)
S_FUNC VALUE
f_aexcsc(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -12187,16 +12222,15 @@ f_aexcsc(int count, VALUE **vals)
/*
* compute inverse exterior trigonometric cosecant to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* firewall */
if (qisnegone(arg1.v_num)) {
if (qisnegone(vals[0]->v_num)) {
return error_value(E_AEXCSC_3);
}
/* try to compute result using real trig function */
result.v_num = qaexcsc_or_NULL(arg1.v_num, eps);
result.v_num = qaexcsc_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -12209,17 +12243,17 @@ f_aexcsc(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_aexcsc(arg1.v_com, eps);
c = c_aexcsc(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_AEXCSC_3);
}
@@ -12234,7 +12268,7 @@ f_aexcsc(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function
@@ -12304,7 +12338,6 @@ f_crd(int count, VALUE **vals)
S_FUNC VALUE
f_acrd(int count, VALUE **vals)
{
VALUE arg1; /* 1st arg if it is a COMPLEX value */
VALUE result; /* value to return */
COMPLEX *c; /* COMPLEX trig result */
NUMBER *eps; /* epsilon error tolerance */
@@ -12328,11 +12361,10 @@ f_acrd(int count, VALUE **vals)
/*
* compute inverse trigonometric chord of a unit circle to a given error tolerance
*/
arg1 = *vals[0];
if (arg1.v_type == V_NUM) {
if (vals[0]->v_type == V_NUM) {
/* try to compute result using real trig function */
result.v_num = qacrd_or_NULL(arg1.v_num, eps);
result.v_num = qacrd_or_NULL(vals[0]->v_num, eps);
/*
* case: trig function returned a NUMBER
@@ -12345,17 +12377,17 @@ f_acrd(int count, VALUE **vals)
*/
} else {
/* convert NUMBER argument from NUMBER to COMPLEX */
arg1.v_com = qqtoc(arg1.v_num, &_qzero_);
arg1.v_type = V_COM;
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM;
}
}
if (arg1.v_type == V_COM) {
if (vals[0]->v_type == V_COM) {
/*
* case: argument was COMPLEX or
* trig function returned NULL and argument was converted to COMPLEX
*/
c = c_acrd(arg1.v_com, eps);
c = c_acrd(vals[0]->v_com, eps);
if (c == NULL) {
return error_value(E_ACRD_3);
}
@@ -12370,7 +12402,7 @@ f_acrd(int count, VALUE **vals)
result.v_type = V_NUM;
}
}
if (arg1.v_type != V_NUM && arg1.v_type != V_COM) {
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
/*
* case: argument type is not valid for this function

View File

@@ -14,7 +14,7 @@ DESCRIPTION
strings available, including the program or script name.
If the numeric arg is supplied, then the corresponding command line
string is return, if it exists. Otherwise a nul() value is returned.
string is return, if it exists. Otherwise a null() value is returned.
In keeping with the argc/argv convention of C, argv(0) will refer
to the name of the program. If the -f filename argument is used,

View File

@@ -152,7 +152,7 @@ Command sequence
exit string
The action of these commands depends on where they are used.
At the interactive level, they will cause calc it edit.
At the interactive level, they will cause calc to exit.
This is the normal way to leave the calculator. In any
other use, they will stop the current calculation as if
an error had occurred.

View File

@@ -8,18 +8,17 @@ TYPES
return string
DESCRIPTION
The ctime() builtin returns the string formed by the first 24
The ctime() builtin returns the string formed by the
characters returned by the C library function, ctime(): E.g.
"Mon Oct 28 00:47:00 1996"
The 25th ctime() character, '\n' is removed.
"Mon Oct 28 00:47:00 1996\n"
EXAMPLE
; ## NOTE: Your output will likely vary:
; printf("The time is now %s.\n", ctime())
The time is now Mon Apr 15 12:41:44 1996.
The time is now Mon Apr 15 12:41:44 1996
.
LIMITS
none

View File

@@ -46,7 +46,7 @@ DESCRIPTION
Some non-POSIX systems such as MS Windows treat text files
and binary files differently. In text mode MS Windows consider
"\r\n" and end-of-line character. On an Apple MAC, the
"\r\n" an end-of-line character. On an Apple MAC, the
text mode end-of-line character is "\r".
Names of files are subject to ~ expansion just like the C or

View File

@@ -100,7 +100,7 @@ DESCRIPTION
Some non-POSIX systems such as MS Windows treat text files
and binary files differently. In text mode MS Windows consider
"\r\n" and end-of-line character. On an Apple MAC, the
"\r\n" an end-of-line character. On an Apple MAC, the
text mode end-of-line character is "\r".
Names of files are subject to ~ expansion just like the C or

View File

@@ -2,7 +2,7 @@ NAME
matfill - fill a matrix with specified value or values
SYNOPSIS
mat(m, x [, y])
matfill(m, x [, y])
TYPES
m matrix

View File

@@ -2,7 +2,7 @@ NAME
mattrans - matrix transpose
SYNOPSIS
matdim(m)
mattrans(m)
TYPES
m 2-dimensional matrix

View File

@@ -1,5 +1,5 @@
NAME
randbit - Blum-Blum-Shub pseudo-random number generator
randombit - Blum-Blum-Shub pseudo-random number generator
SYNOPSIS
randombit([x])

View File

@@ -534,8 +534,15 @@ Unexpected
Some might be surprised to discover that all of the trigonometric in calc:
sin, cos, tan, sec, csc, cot
asin, acos, atan, asec, acsc, acot
sin, cos, tan, cot, sec, csc
asin, acos, atan, acot, asec, acsc
versin, coversin, vercos, covercos
aversin, acoversin, avercos, acovercos
haversin, hacoversin, havercos, hacovercos
ahaversin, hacoversin, havercos, ahacovercos
exsec, aexsec, excsc, aexcsc
crd, acrd
cas, cis
work in only radians.

View File

@@ -38,6 +38,14 @@ export EXIT_CODE=0
# We exclude binary files, RCS source code history, intermediate
# compiled files, patch droppings and compiled binary libraries.
#
# We also ignore filenames with a single letter, and files
# that end in .out, and files containing the any of the following
# in any letter case:
#
# foo bar baz curds whey rmme
#
# Such files are temporary/test files and are not part of calc.
#
# Last, we have two files that have long lines that, for now,
# we cannot be as picky about without significant work.
#
@@ -53,7 +61,9 @@ LEADING_SPACES_BEFORE_TAB=$(
-path './longbits' -o -name '.*.swp' -o -name 'conf.h' -o \
-name '.git' -o -path './custom/libcustcalc*' -o -path './libcustcalc*' -o \
-name 'sample_many-static' -o -name 'sample_rand-static' -o \
-name 'codeql-analysis.yml' -o -name tags -o -name '*.out' \
-name 'codeql-analysis.yml' -o -name tags -o -name '*.out' -o \
-name '?' -o -iname '*foo*' -o -iname '*bar*' -o -iname '*baz*' -o \
-iname '*curds*' -o -iname '*whey*' -o -iname '*rmme*' \
\) -prune -o -type f -print0 | \
xargs -0 egrep -l '^ * * '
)
@@ -69,6 +79,14 @@ fi
# We exclude binary files, RCS source code history, intermediate
# compiled files, patch droppings and compiled binary libraries.
#
# We also ignore filenames with a single letter, and files
# that end in .out, and files containing the any of the following
# in any letter case:
#
# foo bar baz curds whey rmme
#
# Such files are temporary/test files and are not part of calc.
#
# Last, we have two files that have long lines that, for now,
# we cannot be as picky about without significant work.
#
@@ -84,7 +102,8 @@ TRAILING_WHITESPACE=$(
-path './longbits' -o -name '.*.swp' -o -name 'conf.h' -o \
-name '.git' -o -path './custom/libcustcalc*' -o -path './libcustcalc*' -o \
-name 'sample_many-static' -o -name 'sample_rand-static' -o \
-name 'codeql-analysis.yml' -o -name tags -o -name '*.out' \
-name '?' -o -iname '*foo*' -o -iname '*bar*' -o -iname '*baz*' -o \
-iname '*curds*' -o -iname '*whey*' -o -iname '*rmme*' \
\) -prune -o -type f -print0 | \
xargs -0 egrep -l '[ ]$'
)
@@ -139,6 +158,14 @@ fi
# We exclude binary files, source code history, intermediate
# compiled files, patch droppings and compiled binary libraries.
#
# We also ignore filenames with a single letter, and files
# that end in .out, and files containing the any of the following
# in any letter case:
#
# foo bar baz curds whey rmme
#
# Such files are temporary/test files and are not part of calc.
#
# Last, we have files that have long lines that, for now,
# we cannot be as picky about without significant work.
#
@@ -155,7 +182,8 @@ PICKY_PHASE_1=$(
-name '.git' -o -path './custom/libcustcalc*' -o -path './libcustcalc*' -o \
-name 'sample_many-static' -o -name 'sample_rand-static' -o \
-name 'codeql-analysis.yml' -o -name tags -o -name '*.out' -o \
-name '.gitignore' -o -name 'README.md' -o -name '.lldbinit' \
-name '?' -o -iname '*foo*' -o -iname '*bar*' -o -iname '*baz*' -o \
-iname '*curds*' -o -iname '*whey*' -o -iname '*rmme*' \
\) -prune -o -type f -print0 | \
if [[ -x /usr/local/bin/picky ]]; then
xargs -0 /usr/local/bin/picky -s -v -w132
@@ -184,7 +212,7 @@ if [[ -n $BACKUP_MAKEILES ]]; then
echo
echo "# You need execute the following to remove backup Makefiles:"
echo
echo "$BACKUP_MAKEILES" | while read file; do
echo "$BACKUP_MAKEILES" | while read -r file; do
echo "rm -f $file"
done
EXIT_CODE=7

View File

@@ -64,7 +64,7 @@
#define MAJOR_VER 2 /* level 1: major library version */
#define MINOR_VER 15 /* level 2: minor library version */
#define MAJOR_PATCH 0 /* level 3: major software version level */
#define MINOR_PATCH 1 /* level 4: minor software version level */
#define MINOR_PATCH 2 /* level 4: minor software version level */
#endif /* !INCLUDE_VERSION_H*/

View File

@@ -1107,6 +1107,7 @@
* current Blum generator state
*/
STATIC RANDOM blum;
STATIC bool blum_initialized = false; /* true ==> blum has a seeded and initialized state */
/*
@@ -2272,11 +2273,14 @@ zsrandom1(CONST ZVALUE seed, bool need_ret)
/*
* initialize state if first call
*/
if (!blum.seeded) {
if (blum_initialized == false || !blum.seeded) {
p_blum = randomcopy(&init_blum);
randomfree(&blum);
if (blum_initialized == true) {
randomfree(&blum);
}
blum = *p_blum;
free(p_blum);
blum_initialized = true;
}
/*
@@ -2342,6 +2346,9 @@ zsrandom1(CONST ZVALUE seed, bool need_ret)
* reserved seed
*/
} else {
if (ret != NULL) {
randomfree(ret);
}
math_error("srandom seed must be 0 or >= 2^32");
not_reached();
}
@@ -2384,11 +2391,14 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
/*
* initialize state if first call
*/
if (!blum.seeded) {
if (blum_initialized == false || !blum.seeded) {
p_blum = randomcopy(&init_blum);
randomfree(&blum);
if (blum_initialized == true) {
randomfree(&blum);
}
blum = *p_blum;
free(p_blum);
blum_initialized = true;
}
/*
@@ -2409,11 +2419,13 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
* preset moduli only if small newn
*/
if (ziszero(newn)) {
randomfree(ret);
math_error("srandom newn == 0 reserved for future use");
not_reached();
}
set = (HALF)z1tol(newn);
if (!zistiny(newn) || set > BLUM_PREGEN) {
randomfree(ret);
math_error("srandom small newn must be [1,20]");
not_reached();
}
@@ -2433,7 +2445,7 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
* Otherwise non-zero seeds are processed as 1 arg calls
*/
} else {
zsrandom1(seed, false);
(void) zsrandom1(seed, false);
}
/*
@@ -2452,6 +2464,7 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
* Blum modulus must be 1 mod 4
*/
if (newn.v[0] % 4 != 1) {
randomfree(ret);
math_error("srandom large newn must be 1 mod 4");
not_reached();
}
@@ -2498,6 +2511,7 @@ zsrandom2(CONST ZVALUE seed, CONST ZVALUE newn)
* reserved newn
*/
} else {
randomfree(ret);
math_error("srandom newn must be [1,20] or >= 2^32");
not_reached();
}
@@ -2543,11 +2557,14 @@ zsrandom4(CONST ZVALUE seed, CONST ZVALUE ip, CONST ZVALUE iq, long trials)
/*
* initialize state if first call
*/
if (!blum.seeded) {
if (blum_initialized == false || !blum.seeded) {
p_blum = randomcopy(&init_blum);
randomfree(&blum);
if (blum_initialized == true) {
randomfree(&blum);
}
blum = *p_blum;
free(p_blum);
blum_initialized = true;
}
/*
@@ -2559,10 +2576,12 @@ zsrandom4(CONST ZVALUE seed, CONST ZVALUE ip, CONST ZVALUE iq, long trials)
* search the 'p' and 'q' Blum prime (3 mod 4) candidates
*/
if (!znextcand(ip, trials, _zero_, _three_, _four_, &p)) {
randomfree(ret);
math_error("failed to find 1st Blum prime");
not_reached();
}
if (!znextcand(iq, trials, _zero_, _three_, _four_, &q)) {
randomfree(ret);
math_error("failed to find 2nd Blum prime");
not_reached();
}
@@ -2640,11 +2659,14 @@ zsetrandom(CONST RANDOM *state)
/*
* initialize state if first call
*/
if (!blum.seeded) {
if (blum_initialized == false || !blum.seeded) {
p_blum = randomcopy(&init_blum);
randomfree(&blum);
if (blum_initialized == true) {
randomfree(&blum);
}
blum = *p_blum;
free(p_blum);
blum_initialized = true;
}
/*
@@ -2684,11 +2706,14 @@ zrandomskip(long cnt)
/*
* initialize state if first call
*/
if (!blum.seeded) {
if (blum_initialized == false || !blum.seeded) {
p_blum = randomcopy(&init_blum);
randomfree(&blum);
if (blum_initialized == true) {
randomfree(&blum);
}
blum = *p_blum;
free(p_blum);
blum_initialized = true;
}
loglogn = (long)blum.loglogn;
new_r.len = 0; /* paranoia */
@@ -2798,11 +2823,14 @@ zrandom(long cnt, ZVALUE *res)
/*
* initialize state if first call
*/
if (!blum.seeded) {
if (blum_initialized == false || !blum.seeded) {
p_blum = randomcopy(&init_blum);
randomfree(&blum);
if (blum_initialized == true) {
randomfree(&blum);
}
blum = *p_blum;
free(p_blum);
blum_initialized = true;
}
loglogn = blum.loglogn;
mask = blum.mask;
@@ -3120,16 +3148,18 @@ randomfree(RANDOM *state)
not_reached();
}
/* free the values */
/* clear the seed */
state->seeded = 0;
state->bits = 0; /* paranoia */
state->loglogn = 0; /* paranoia */
state->buffer = 0; /* paranoia */
state->mask = 0; /* paranoia */
/* free the values - unless they are one of the default states */
zfree_random(state->n);
zfree_random(state->r);
/* free it if it is not pre-defined */
state->seeded = 0;
state->bits = 0; /* paranoia */
state->buffer = 0;
/* free it if it is not pre-defined */
/* free the RANDOM structure if it is NOT our static blum value */
if (state != &blum) {
free(state);
}
@@ -3223,8 +3253,10 @@ randomprint(CONST RANDOM *UNUSED(state), int UNUSED(flags))
void
random_libcalc_cleanup(void)
{
/* free our state - let zfree_random protect the default state */
randomfree(&blum);
/* free our state if seed was initialized - zfree_random protect default states */
if (blum_initialized == true && blum.seeded) {
randomfree(&blum);
}
return;
}
@@ -3238,6 +3270,7 @@ random_libcalc_cleanup(void)
S_FUNC void
zfree_random(ZVALUE z)
{
/* do not free if NULL or one of the default states */
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 &&