mirror of
https://github.com/lcn2/calc.git
synced 2025-08-22 01:23:28 +03:00
Compare commits
100 Commits
prod-2.15.
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
f1a4cb6313 | ||
|
59d47e80fb | ||
|
95793c3150 | ||
|
077ba65285 | ||
|
f912da9427 | ||
|
753b101e54 | ||
|
db83b7383f | ||
|
d9245844aa | ||
|
8542143463 | ||
|
50cb6ec798 | ||
|
41951e2c09 | ||
|
b9cee333b2 | ||
|
e35bb7ffa6 | ||
|
c5b64c373b | ||
|
4017579aeb | ||
|
88fb6a4e47 | ||
|
7eb7e9de1f | ||
|
42d5749da2 | ||
|
bbcbb76369 | ||
|
232b3bddef | ||
|
5ac3e495b2 | ||
|
56153d6615 | ||
|
2a4f399593 | ||
|
160de4bb38 | ||
|
db77e29a23 | ||
|
fe9cefe6ef | ||
|
ea4c50ade0 | ||
|
7f72908b95 | ||
|
a547c36f0a | ||
|
1e2698b42d | ||
|
33815f49e6 | ||
|
732279bcc3 | ||
|
7f4e1eb68d | ||
|
1232b59949 | ||
|
90feefc622 | ||
|
c97ee188ad | ||
|
ae85846839 | ||
|
e096bd9ad8 | ||
|
884b1bc81b | ||
|
a30a518ba7 | ||
|
bb3b861090 | ||
|
0a3469125e | ||
|
9b37e79f21 | ||
|
18cd1f9067 | ||
|
43fc022dc8 | ||
|
29695028cd | ||
|
1d37930d22 | ||
|
60698d2130 | ||
|
3e7ccfd31c | ||
|
488d81b809 | ||
|
932d27053e | ||
|
8e8d6c852a | ||
|
54dd89dcf7 | ||
|
d91e966f19 | ||
|
8d6f83ad91 | ||
|
8dd380a9f7 | ||
|
fbaff69c92 | ||
|
c724227ef9 | ||
|
3fd64578a6 | ||
|
c9c4105ddc | ||
|
80b7cd34fe | ||
|
630947d35c | ||
|
45f62fd7b4 | ||
|
8ca980b2bb | ||
|
2ace631d00 | ||
|
41d339c60e | ||
|
cc3bb98fa0 | ||
|
2b506a74e7 | ||
|
826d2d8175 | ||
|
af8ffb3098 | ||
|
71dd30c4c6 | ||
|
8ca96a8c29 | ||
|
0bba80c92b | ||
|
c1882e2ea0 | ||
|
79964338d1 | ||
|
d809ce5cf0 | ||
|
daac7b35af | ||
|
40d6e22318 | ||
|
ab2038ecbc | ||
|
0b57d6b605 | ||
|
01f0605055 | ||
|
0e6016f429 | ||
|
2d2e1c5894 | ||
|
50ba5f9a3e | ||
|
850cdbef1d | ||
|
21cedfcae4 | ||
|
4fa137a638 | ||
|
6ebe707670 | ||
|
885db22315 | ||
|
06a9997da7 | ||
|
fae4b8e81b | ||
|
ddf0c8f1f5 | ||
|
d52cbcea14 | ||
|
d14d525a6a | ||
|
698f73cd3e | ||
|
e1888d9b9e | ||
|
b54f68a797 | ||
|
77d7e665e0 | ||
|
e96ef61718 | ||
|
0eee1a615d |
43
.github/workflows/codeql-analysis.yml
vendored
43
.github/workflows/codeql-analysis.yml
vendored
@@ -13,10 +13,10 @@ name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '41 1 * * 6'
|
||||
|
||||
@@ -33,39 +33,48 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v5
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
14
.github/workflows/dependency-review.yml
vendored
Normal file
14
.github/workflows/dependency-review.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: 'Dependency Review'
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
dependency-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v5
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@v4
|
32
.gitignore
vendored
32
.gitignore
vendored
@@ -1,17 +1,17 @@
|
||||
# generic excluded patterns
|
||||
#
|
||||
# We sort the list below via: sort -u -f
|
||||
# We sort the list below via: sort -d -u
|
||||
#
|
||||
*,v
|
||||
*~
|
||||
*.BAK
|
||||
core*
|
||||
.DS_Store
|
||||
*.dSYM/
|
||||
*.exe
|
||||
*.o.tmp
|
||||
*.[oa]
|
||||
*~
|
||||
*.o.tmp
|
||||
.*.swp
|
||||
.DS_Store
|
||||
core*
|
||||
*,v
|
||||
|
||||
# files and directories created during the building of calc and other Makefile actions
|
||||
#
|
||||
@@ -19,30 +19,28 @@ core*
|
||||
# not consider development source. Some other file(s) and/or programs
|
||||
# generate these files.
|
||||
#
|
||||
# We sort the list below via: sort -u -f
|
||||
# We sort the list below via: sort -d -u
|
||||
#
|
||||
.dynamic
|
||||
.hsrc
|
||||
.static
|
||||
align32
|
||||
align32.h
|
||||
align32_tmp
|
||||
arc4random_tmp
|
||||
args.h
|
||||
cal/.all
|
||||
cal/test082.cal
|
||||
calc
|
||||
calc-static
|
||||
calc.1
|
||||
calc.cat1
|
||||
calc.spec
|
||||
calc-static
|
||||
calc.usage
|
||||
cal/test082.cal
|
||||
charbit.h
|
||||
chatbit
|
||||
chk_c
|
||||
conf.h
|
||||
const_tmp
|
||||
cscript/.all
|
||||
cscript/4dsphere
|
||||
cscript/.all
|
||||
cscript/fproduct
|
||||
cscript/mersenne
|
||||
cscript/piforever
|
||||
@@ -54,15 +52,16 @@ cscript/square
|
||||
custom/.all
|
||||
custom/libcustcalc*
|
||||
debug.out
|
||||
.dynamic
|
||||
endian
|
||||
endian_calc.h
|
||||
environ_tmp
|
||||
errcode
|
||||
errsym.h
|
||||
fpos_tmp
|
||||
fposval
|
||||
fposval.h
|
||||
fposval_tmp
|
||||
fpos_tmp
|
||||
func.show
|
||||
func.sort
|
||||
getpgid_tmp
|
||||
@@ -91,8 +90,6 @@ have_gettime
|
||||
have_gettime.h
|
||||
have_inttypes.h
|
||||
have_limits.h
|
||||
have_memmv
|
||||
have_memmv.h
|
||||
have_newstr
|
||||
have_newstr.h
|
||||
have_offscl
|
||||
@@ -156,13 +153,13 @@ help/releases
|
||||
help/resource
|
||||
help/type
|
||||
help/usage
|
||||
.hsrc
|
||||
libcalc.*
|
||||
libcustcalc.*
|
||||
ll_tmp
|
||||
longbits
|
||||
longbits.h
|
||||
Makefile.our
|
||||
memmv_tmp
|
||||
newstr_tmp
|
||||
NOTES
|
||||
offscl_tmp
|
||||
@@ -174,6 +171,7 @@ sample_many-static
|
||||
sample_rand
|
||||
sample_rand-static
|
||||
statfs_tmp
|
||||
.static
|
||||
status.chk_c.h
|
||||
strdup_tmp
|
||||
tags
|
||||
|
4
BUGS
4
BUGS
@@ -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
|
||||
|
226
CHANGES
226
CHANGES
@@ -1,4 +1,201 @@
|
||||
The following are the changes from calc version 2.14.3.5 to 2.15.0.0:
|
||||
The following are the changes from calc version 2.15.1.2 to 2.16.0.0:
|
||||
|
||||
Starting with calc version 2.16.0.0, the ability to perform arithmetic
|
||||
on addresses of values in calc objects has been greatly restricted.
|
||||
|
||||
Most arithmetic on of value addresses could easily cause calc to
|
||||
crash. For example, prior to calc version 2.16.0.0, the following
|
||||
command was likely to crash calc:
|
||||
|
||||
calc '*((&.)+1e9)'
|
||||
|
||||
Subtracting two value addresses is permitted, however there is NO
|
||||
guarantee that the address of a value will remain consistent across
|
||||
calc runs. Addresses of values depend on the circumstances of when
|
||||
the calc values were formed.
|
||||
|
||||
The above restrictions and caveats apply to addresses of values.
|
||||
Such restrictions and caveats to NOT apply to the addresses of
|
||||
octets, NOR to the addresses within strings. If isptr(x) == 2, then
|
||||
x is value-pointer and the above mentioned restrictions and caveats apply.
|
||||
|
||||
See "help address" for more information on value address arithmetic.
|
||||
|
||||
Added E_INVALID_DEREF (10610) error code to indicate the invalid
|
||||
dereferencing a non-variable.
|
||||
|
||||
Added E_INVALID_ADDR_OP (10611) error code to indicate an invalid
|
||||
arithmetic address operation.
|
||||
|
||||
We plan to let this most recent change settle down before performing
|
||||
the calc v2 to calc v3 fork. Therefore, version 2.16.1.0 will form
|
||||
the basis for the calc v2 to calc v3 fork.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.15.1.2 to 2.15.1.2:
|
||||
|
||||
Removed use of HAVE_MEMMOVE as well have_memmv.c. Removed the
|
||||
building and including of have_memmv.h. Removed the memmove()
|
||||
function in blkcpy.c, used when HAVE_MEMMOVE was NOT defined.
|
||||
The libc memmove(3) function as defined by <string.h> is now
|
||||
required to compile calc because the replacement code in
|
||||
blkcpy.c q was problematic, especially when regions overlap.
|
||||
The HAVE_MEMMOVE make symbol was removed from Makefile.config.
|
||||
Thanks to GitHub user @skeeto for reporting this problem.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.15.1.1 to 2.15.1.1:
|
||||
|
||||
Change Makefile.config to, if not using not HomeBrew, then try to
|
||||
detect macports and/or using /opt/local/{lib,include}.
|
||||
|
||||
Put full date range (1989-2025) of calc source into version.h.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.15.0.7 to 2.15.1.0:
|
||||
|
||||
Converted all ASCII tabs to ASCII spaces using a 8 character
|
||||
tab stop, for all files, except for all Makefiles (plus rpm.mk).
|
||||
The command `git diff -w` reports no changes. There is no
|
||||
functionality change in calc: only ASCII tabs to ASCII spaces.
|
||||
|
||||
Fixed trailblank. It was pruning . in its find search.
|
||||
Added check for ASCII tabs is non-Makefiles.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.15.0.6 to 2.15.0.7:
|
||||
|
||||
Thanks to GitHub user @bambooleafz a critical bug (GitHub issue
|
||||
#148 - https://github.com/lcn2/calc/issues/148) they identified
|
||||
was fixed.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.15.0.5 to 2.15.0.6:
|
||||
|
||||
Thanks to GitHub user @ashamedbit, a long standing memory leak in
|
||||
zrandom.c has been fixed.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.15.0.4 to 2.15.0.5:
|
||||
|
||||
make clobber now removes the legacy files: have_fpos.h, help/man,
|
||||
and help/usage. The latter 2 are now managed as help aliases
|
||||
in help.c.
|
||||
|
||||
make install now removes the legacy files: ${HELPDIR}/man
|
||||
and ${HELPDIR}/usage.
|
||||
|
||||
Fixed a problem where, when calc was linked with and uses GNU
|
||||
readline then for any multi-line copy-and-paste, only the first
|
||||
line is executed. Thanks to GitHub user @malfisya for reporting
|
||||
this problem, and thanks to GitHub user @gromit1811 for doing
|
||||
the research needed to overcome deficiencies in the GNU readline
|
||||
documentation, and for supplying the work-a-round to allow
|
||||
multi-line copy-and-paste to work as expected!
|
||||
|
||||
|
||||
The following are the changes from calc version 2.15.0.3 to 2.15.0.4:
|
||||
|
||||
Fixed bug that caused calc to fail to compile filepos2z() in file.c
|
||||
on little endian machines for the Debian apcalc package. Thanks to
|
||||
Martin Buck (m at rtin-buck dor de) for for fix.
|
||||
|
||||
Removed unused macros from zmath.h:
|
||||
|
||||
SWAP_B32_IN_HASH(dest, src)
|
||||
SWAP_B16_IN_HASH(dest, src)
|
||||
SWAP_B8_IN_HASH(dest, src)
|
||||
SWAP_B32_IN_FLAG(dest, src)
|
||||
SWAP_B16_IN_FLAG(dest, src)
|
||||
SWAP_B8_IN_FLAG(dest, src)
|
||||
|
||||
When SWAP_HALF_IN_B32(dest, src), SWAP_B32_IN_FULL(dest, src),
|
||||
SWAP_B16_IN_HALF(dest, src), SWAP_B32_IN_bool(dest, src),
|
||||
or SWAP_B32_IN_LEN(dest, src), SWAP_HALF_IN_FILEPOS(dest, src)
|
||||
is an assignment such as:
|
||||
|
||||
(*(dest) = *(src))
|
||||
|
||||
We now case the dest and src pointers to the proper type before
|
||||
referencing and performing the assignment.
|
||||
|
||||
Documented unexpected behavior when calc is running in
|
||||
"shell script mode" and the prompt builtin function is used
|
||||
without the -p flag. Updated help/prompt, help/unexpected
|
||||
and the calc man page accordingly.
|
||||
|
||||
Unless calc is given the -p command line option, calc will reopen
|
||||
stdin as /dev/null instead of just closing stdin. This prevents
|
||||
subsequent opens grabbing the 1st file descriptor.
|
||||
|
||||
Disable regress tests 4709, 4710, and 7763 because they print
|
||||
multi-byte sequences, which are just fine for calc, the awk
|
||||
used to evaluate the regression suite output in some legacy
|
||||
systems report a "multibyte conversion failure".
|
||||
|
||||
Added a number of missing Makefile variables to the "make env" rule.
|
||||
|
||||
The man command is used to format the calc.1 man page into calc.usage.
|
||||
|
||||
The "help calc" command now prints the formatted calc man page (calc.usage).
|
||||
The "help man" command now prints the formatted calc man page (calc.usage).
|
||||
The "help usage" command now prints the formatted calc man page (calc.usage).
|
||||
|
||||
The file, calc.cat1, is formed by gzipping the calc.usage
|
||||
formatted man page. The calc.cat1 is installed as the calc
|
||||
cat section 1 man page.
|
||||
|
||||
Updated the Copyright string in version.c to refer to
|
||||
the COPYING file and the "help copying" command.
|
||||
|
||||
Added calc.cat1 to .gitignore. Using "sort -d -u" to sort .gitignore content.
|
||||
|
||||
Avoiding use of modern [[ and ]] in Makefile for those legacy systems
|
||||
whose shell do not support them. Be sure to use ||'s between []'s
|
||||
to avoid problems with legacy shell such as the Bourne shell. *sigh*
|
||||
|
||||
Fixed the order of "help full" to match the order of topics listed
|
||||
buy the "help help" command.
|
||||
|
||||
Sorted the halias[] help topics table in help.c using sort -d -u.
|
||||
|
||||
|
||||
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.
|
||||
The version.h is now listed as part of the calc distribution.
|
||||
|
||||
Added the following new trigonometric functions:
|
||||
|
||||
@@ -434,6 +631,31 @@ The following are the changes from calc version 2.14.3.4 to 2.14.3.5:
|
||||
Added errsym E_LOG2_4 for log2(0).
|
||||
Added errsym E_LOGN_6 for logn(0,base).
|
||||
|
||||
Added a chk_tree tool to help look for problems such as files that are
|
||||
result of building calc that are also part of the calc distribution,
|
||||
and files that are part of the calc source that are missing from the
|
||||
calc distribution, and files that are of unknown status that are either
|
||||
result of building calc nor missing from the calc distribution.
|
||||
|
||||
Updated file lists in Makefile, sorting as needed.
|
||||
|
||||
Updated Makefile PHONY rule to include Makefile rules that are NOT files.
|
||||
|
||||
Reduced make chatter for rules that build lists.
|
||||
|
||||
Added make verifydist to verify the existence of files that are part of
|
||||
the calc distribution.
|
||||
|
||||
Added make verifydist to make prep.
|
||||
|
||||
Added a chk_tree double check, one after make clobber, one before
|
||||
the final make chk, to make prep. Added double pass of chk_tree to
|
||||
make full_debug (and thus to the make debug output).
|
||||
|
||||
Improved notes for install locations in Makefile.config.
|
||||
|
||||
Added printing of ${BUILD_ALL} to make env output.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.14.3.0 to 2.14.3.4:
|
||||
|
||||
@@ -4200,7 +4422,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:
|
||||
|
110
Makefile.config
110
Makefile.config
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Makefile.config - Calc configuration and compile configuration values
|
||||
#
|
||||
# Copyright (C) 2023 Landon Curt Noll
|
||||
# Copyright (C) 2023,2025 Landon Curt Noll
|
||||
#
|
||||
# Suggestion: Read the HOWTO.INSTALL file.
|
||||
#
|
||||
@@ -436,18 +436,6 @@ HAVE_ARC4RANDOM=
|
||||
HAVE_NEWSTR=
|
||||
#HAVE_NEWSTR= -DHAVE_NO_NEWSTR
|
||||
|
||||
# Determine if we have memmove()
|
||||
#
|
||||
# If HAVE_MEMMOVE is empty, this Makefile will run the have_memmv program
|
||||
# to determine if memmove() is supported. If HAVE_MEMMOVE is set to
|
||||
# -DHAVE_NO_MEMMOVE, then calc will use internal functions to simulate
|
||||
# the memory move function that does correct overlapping memory moves.
|
||||
#
|
||||
# If in doubt, leave HAVE_MEMMOVE empty and this Makefile will figure it out.
|
||||
#
|
||||
HAVE_MEMMOVE=
|
||||
#HAVE_MEMMOVE= -DHAVE_NO_MEMMOVE
|
||||
|
||||
# Determine if we have ustat()
|
||||
#
|
||||
# If HAVE_USTAT is empty, this Makefile will run the have_ustat program
|
||||
@@ -852,12 +840,21 @@ endif # ($(target),Darwin)
|
||||
# BINDIR= /usr/bin
|
||||
# LIBDIR= /usr/lib
|
||||
# CALC_SHAREDIR= /usr/share/calc
|
||||
# CALC_INCDIR= /usr/include/calc
|
||||
#
|
||||
# Or if you prefer everything under /usr/local:
|
||||
#
|
||||
# BINDIR= /usr/local/bin
|
||||
# LIBDIR= /usr/local/lib
|
||||
# CALC_SHAREDIR= /usr/local/share/calc
|
||||
# CALC_INCDIR= /usr/local/include/calc
|
||||
#
|
||||
# However, if you are on macOS then set:
|
||||
#
|
||||
# BINDIR= ${PREFIX}/bin
|
||||
# LIBDIR= ${PREFIX}/lib
|
||||
# CALC_SHAREDIR= ${PREFIX}/share/calc
|
||||
# CALC_INCDIR= ${PREFIX}/include/calc
|
||||
#
|
||||
# NOTE: Starting with macOS El Capitan OS X 10.11, root by default
|
||||
# could not mkdir under system locations, so macOS must now
|
||||
@@ -988,9 +985,6 @@ endif # ($(target),Darwin)
|
||||
#
|
||||
# Use CATDIR= to disable installation of the calc cat (formatted) page.
|
||||
#
|
||||
# NOTE: If CATDIR is non-empty, then one should have either the
|
||||
# ${NROFF} executable and/or the ${MANMAKE} executable.
|
||||
#
|
||||
CATDIR=
|
||||
#CATDIR= ${PREFIX}/man/cat1
|
||||
#CATDIR= ${PREFIX}/catman/cat1
|
||||
@@ -1017,36 +1011,6 @@ CATEXT= 1
|
||||
#CATEXT= 0
|
||||
#CATEXT= l
|
||||
|
||||
# how to format a man page
|
||||
#
|
||||
# If CATDIR is non-empty, then
|
||||
#
|
||||
# If NROFF is non-empty, then
|
||||
#
|
||||
# ${NROFF} ${NROFF_ARG} calc.1 > ${CATDIR}/calc.${CATEXT}
|
||||
# is used to build and install the cat page
|
||||
#
|
||||
# else (NROFF is empty)
|
||||
#
|
||||
# ${MANMAKE} calc.1 ${CATDIR}
|
||||
# is used to build and install the cat page
|
||||
# else
|
||||
#
|
||||
# The cat page is not built or installed
|
||||
#
|
||||
# If in doubt and you don't want to fool with man pages, set MANDIR
|
||||
# and CATDIR to empty and ignore the NROFF, NROFF_ARG and MANMAKE
|
||||
# lines below.
|
||||
#
|
||||
#NROFF= nroff
|
||||
NROFF=
|
||||
#NROFF= groff
|
||||
NROFF_ARG= -man
|
||||
#NROFF_ARG= -mandoc
|
||||
MANMAKE= ${PREFIX}/bin/manmake
|
||||
#MANMAKE= manmake
|
||||
MANMODE= 0444
|
||||
CATMODE= 0444
|
||||
|
||||
# By default, custom builtin functions may only be executed if calc
|
||||
# is given the -C option. This is because custom builtin functions
|
||||
@@ -1136,6 +1100,9 @@ READLINE_EXTRAS= -lhistory -lncurses
|
||||
#READLINE_LIB= -L${PREFIX}/lib -lreadline
|
||||
#READLINE_EXTRAS= -lhistory -lncurses
|
||||
#
|
||||
#READLINE_LIB= -L/opt/local/lib -lreadline
|
||||
#READLINE_EXTRAS= -lhistory -lncurses
|
||||
#
|
||||
# For Apple OS X: install fink from http://fink.sourceforge.net
|
||||
# and then do a 'fink install readline' and then use:
|
||||
#
|
||||
@@ -1154,6 +1121,7 @@ READLINE_EXTRAS= -lhistory -lncurses
|
||||
READLINE_INCLUDE=
|
||||
#READLINE_INCLUDE= -I/usr/gnu/include
|
||||
#READLINE_INCLUDE= -I${PREFIX}/include
|
||||
#READLINE_INCLUDE= -I/opt/local/include
|
||||
|
||||
# Handle the case where macOS is being used with HomeBrew
|
||||
# # and using the readline, history, and ncurses libraries.
|
||||
@@ -1161,6 +1129,16 @@ READLINE_INCLUDE=
|
||||
ifneq ($(HOMEBREW_PREFIX),)
|
||||
READLINE_LIB:= -L${HOMEBREW_PREFIX}/opt/readline/lib -lreadline
|
||||
READLINE_INCLUDE:= -I${HOMEBREW_PREFIX}/opt/readline/include
|
||||
|
||||
# If not HomeBrew, then try to detect macports and/or using /opt/local/{lib,include}
|
||||
#
|
||||
else # perhaps macports and/or using /opt/local/{lib,include} ?
|
||||
ifneq ($(wildcard /opt/local/lib/*),)
|
||||
READLINE_LIB:= -L/opt/local/lib -lreadline
|
||||
endif
|
||||
ifneq ($(wildcard /opt/local/incliude/*),)
|
||||
READLINE_INCLUDE:= -I/opt/local/include
|
||||
endif
|
||||
endif # ($(HOMEBREW_PREFIX),)
|
||||
|
||||
# If $PAGER is not set, use this program to display a help file
|
||||
@@ -1267,11 +1245,11 @@ EXT=
|
||||
|
||||
# The calc version in the form of x.y.z.w
|
||||
#
|
||||
VERSION= 2.15.0.0
|
||||
VERSION= 2.16.0.0
|
||||
|
||||
# The calc major version in the form of x.y.z
|
||||
#
|
||||
VER= 2.15.0
|
||||
VER= 2.16.0
|
||||
|
||||
# Names of shared libraries with versions
|
||||
#
|
||||
@@ -1287,13 +1265,13 @@ CAT= cat
|
||||
CHMOD= chmod
|
||||
CMP= cmp
|
||||
CO= co
|
||||
COL= col
|
||||
CP= cp
|
||||
CTAGS= ctags
|
||||
DATE= date
|
||||
DIFF= diff
|
||||
FMT= fmt
|
||||
GREP= grep
|
||||
GZIP= gzip
|
||||
HOSTNAME= hostname
|
||||
LANG= C
|
||||
LDCONFIG= ldconfig
|
||||
@@ -1301,6 +1279,7 @@ LN= ln
|
||||
LS= ls
|
||||
MAKE= make
|
||||
MAKEDEPEND= makedepend
|
||||
MAN= man
|
||||
MKDIR= mkdir
|
||||
MV= mv
|
||||
PWDCMD= pwd
|
||||
@@ -1312,8 +1291,8 @@ SORT= sort
|
||||
SPLINT= splint
|
||||
SPLINT_OPTS=
|
||||
STRIP= strip
|
||||
TEE= tee
|
||||
TAIL= tail
|
||||
TEE= tee
|
||||
TOUCH= touch
|
||||
TRUE= true
|
||||
UNAME= uname
|
||||
@@ -1373,3 +1352,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 RHEL9.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
|
||||
|
@@ -50,64 +50,51 @@
|
||||
###################################################################
|
||||
|
||||
####
|
||||
# RHEL Diagnosing memory, thread, and crash issues:
|
||||
# Force calc to install under /usr/local
|
||||
#
|
||||
# For more info see: https://github.com/google/sanitizers/wiki/AddressSanitizer
|
||||
#
|
||||
# This comment block was tested under:
|
||||
#
|
||||
# RHEL9 gcc version 11.3.1 20221121 (Red Hat 11.3.1-4) (GCC)
|
||||
#
|
||||
# with:
|
||||
#
|
||||
# libasan-11.3.1-4.3.el9.x86_64 libubsan-11.3.1-4.3.el9.x86_64
|
||||
#
|
||||
# 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
|
||||
# PREFIX:= /usr/local
|
||||
# BINDIR:= ${PREFIX}/bin
|
||||
# LIBDIR:= ${PREFIX}/lib
|
||||
# CALC_SHAREDIR:= ${PREFIX}/share/calc
|
||||
# CALC_INCDIR:= ${PREFIX}/include/calc
|
||||
####
|
||||
|
||||
####
|
||||
# macOS 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:
|
||||
#
|
||||
# macOS 13.5 with clang version 14.0.3 (clang-1403.0.22.14.1)
|
||||
# macOS 14.0 with Apple clang version 15.0.0 (clang-1500.0.40.1) for arm64
|
||||
#
|
||||
# For more info for clang to Diagnosing memory, thread, and crash issues early, see:
|
||||
# See the FSANITIZE comment block in Makefile.config for common FSANITIZE values and more info.
|
||||
#
|
||||
# https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early
|
||||
# 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-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
|
||||
###
|
||||
|
@@ -8,7 +8,7 @@ on Debian: sudo apt install calc
|
||||
on RHEL: sudo dnf install calc
|
||||
on Ubuntu: sudo apt install calc
|
||||
via Termux: apt install calc
|
||||
via src: sudo make clobber all chk instsll
|
||||
via src: sudo make clobber all chk install
|
||||
```
|
||||
|
||||
## TL;DR Run calc
|
||||
@@ -283,3 +283,8 @@ help unexpected
|
||||
|
||||
It contains information about differences between C and calc
|
||||
that may surprise C programmers.
|
||||
|
||||
|
||||
# Reporting Security Issues
|
||||
|
||||
To report a security issue, please visit "[Reporting Security Issues](https://github.com/lcn2/calc/security/policy)".
|
||||
|
22
SECURITY.md
22
SECURITY.md
@@ -1,4 +1,16 @@
|
||||
# Security Policy
|
||||
# Reporting Security Issues
|
||||
|
||||
We take security bugs seriously. We appreciate your efforts to responsibly
|
||||
disclose your findings, and will make every effort to acknowledge your
|
||||
contributions for any verified security issues when they have been fixed.
|
||||
|
||||
To report a security issue, click on: "[Open a draft security advisory](https://github.com/lcn2/calc/security/advisories/new)"
|
||||
|
||||
We will send a response indicating the next steps in handling your
|
||||
report. After the initial reply to your report, we will keep you informed
|
||||
of the progress towards a fix and full announcement, and may ask for
|
||||
additional information or guidance.
|
||||
|
||||
|
||||
## Supported Versions
|
||||
|
||||
@@ -9,11 +21,3 @@ If the most recent stable of calc is also supported with security updates.
|
||||
FYI: please review the BUGS file, or enter the calc command:
|
||||
|
||||
; help BUGS
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please create a calc GitHub repo issue:
|
||||
|
||||
https://github.com/lcn2/calc/issues
|
||||
|
||||
Click on ((New issue)) and follow the issue template.
|
||||
|
19
alloc.h
19
alloc.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* alloc - storage allocation and storage debug macros
|
||||
*
|
||||
* Copyright (C) 1999-2007,2014 David I. Bell
|
||||
* Copyright (C) 1999-2007,2014,2025 David I. Bell
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -29,13 +29,15 @@
|
||||
|
||||
|
||||
#if defined(CALC_SRC) /* if we are building from the calc source tree */
|
||||
# include "decl.h"
|
||||
# include "have_newstr.h"
|
||||
# include "have_string.h"
|
||||
# include "have_memmv.h"
|
||||
# include "have_const.h"
|
||||
#else
|
||||
# include <calc/decl.h>
|
||||
# include <calc/have_newstr.h>
|
||||
# include <calc/have_string.h>
|
||||
# include <calc/have_memmv.h>
|
||||
# include <calc/have_const.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
@@ -75,15 +77,4 @@ E_FUNC int strcmp();
|
||||
#define strchr(s, c) index(s, c)
|
||||
#endif /* HAVE_NEWSTR */
|
||||
|
||||
#if !defined(HAVE_MEMMOVE)
|
||||
# undef MEMMOVE_SIZE_T
|
||||
#if defined(FORCE_STDC) || \
|
||||
(defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
|
||||
# define MEMMOVE_SIZE_T size_t
|
||||
# else
|
||||
# define MEMMOVE_SIZE_T long
|
||||
# endif
|
||||
E_FUNC void *memmove(void *s1, CONST void *s2, MEMMOVE_SIZE_T n);
|
||||
#endif
|
||||
|
||||
#endif /* !INCLUDE_ALLOC_H */
|
||||
|
58
blkcpy.c
58
blkcpy.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkcpy - general values and related routines used by the calculator
|
||||
*
|
||||
* Copyright (C) 1999-2007,2021-2023 Landon Curt Noll and Ernest Bowen
|
||||
* Copyright (C) 1999-2007,2021-2023,2025 Landon Curt Noll and Ernest Bowen
|
||||
*
|
||||
* Primary author: Landon Curt Noll
|
||||
*
|
||||
@@ -924,62 +924,6 @@ copyostr2blk(char *str,long ssi,long num,BLOCK *dblk,long dsi,bool noreloc)
|
||||
dblk->datalen = newlen;
|
||||
return 0;
|
||||
}
|
||||
#if !defined(HAVE_MEMMOVE)
|
||||
/*
|
||||
* memmove - simulate the memory move function that deals with overlap
|
||||
*
|
||||
* Copying between objects that overlap will take place correctly.
|
||||
*
|
||||
* given:
|
||||
* s1 destination
|
||||
* s2 source
|
||||
* n octet count
|
||||
*
|
||||
* returns:
|
||||
* s1
|
||||
*/
|
||||
void *
|
||||
memmove(void *s1, CONST void *s2, MEMMOVE_SIZE_T n)
|
||||
{
|
||||
/*
|
||||
* firewall
|
||||
*/
|
||||
if (s1 == NULL || s2 == NULL) {
|
||||
math_error("bogus memmove NULL ptr");
|
||||
not_reached();
|
||||
}
|
||||
if (n <= 0) {
|
||||
/* neg or 0 count does nothing */
|
||||
return s1;
|
||||
}
|
||||
if ((char *)s1 == (char *)s2) {
|
||||
/* copy to same location does nothing */
|
||||
return s1;
|
||||
}
|
||||
|
||||
/*
|
||||
* determine if we need to deal with overlap copy
|
||||
*/
|
||||
if ((char *)s1 > (char *)s2 && (char *)s1 < (char *)s2+n) {
|
||||
|
||||
/*
|
||||
* we have to copy backwards ... slowly
|
||||
*/
|
||||
while (n-- > 0) {
|
||||
((char *)s1)[n] = ((char *)s2)[n];
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* safe ... no overlap problems
|
||||
*/
|
||||
(void) memcpy(s1, s2, n);
|
||||
|
||||
}
|
||||
return s1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
16
cal/Makefile
16
cal/Makefile
@@ -159,10 +159,11 @@ DISTLIST= ${CALC_FILES} ${MAKE_FILE}
|
||||
# These files are used to make (but not built) a calc .a link library
|
||||
#
|
||||
CALCLIBLIST=
|
||||
#
|
||||
|
||||
# rules that are not also names of files
|
||||
#
|
||||
PHONY= all clobber distlist install
|
||||
PHONY= all distlist buildlist distdir calcliblist calc_files_list echo_inst_files \
|
||||
clean clobber install uninstall
|
||||
|
||||
|
||||
############################################################
|
||||
@@ -182,14 +183,14 @@ all: ${CALC_FILES} ${MAKE_FILE} .all
|
||||
# additional Makefile targets #
|
||||
###############################
|
||||
|
||||
.PHONY: ${PHONY}
|
||||
|
||||
# used by the upper level Makefile to determine of we have done all
|
||||
#
|
||||
.all:
|
||||
${RM} -f .all
|
||||
${TOUCH} .all
|
||||
|
||||
.PHONY: ${PHONY}
|
||||
|
||||
##
|
||||
#
|
||||
# File list generation. You can ignore this section.
|
||||
@@ -210,6 +211,13 @@ distlist: ${DISTLIST}
|
||||
fi; \
|
||||
done
|
||||
|
||||
buildlist:
|
||||
${Q} for i in ${BUILD_ALL} /dev/null; do \
|
||||
if [ X"$$i" != X"/dev/null" ]; then \
|
||||
echo cal/$$i; \
|
||||
fi; \
|
||||
done | fgrep -v '.bak' | LANG=C ${SORT}
|
||||
|
||||
distdir:
|
||||
${Q} echo cal
|
||||
|
||||
|
121
cal/regress.cal
121
cal/regress.cal
@@ -3030,6 +3030,24 @@ define test_2600()
|
||||
strcat(str(tnum++),
|
||||
': round(log(1.2+1.2i,1e-10),10) == ',
|
||||
'0.2296962439+0.3410940885i'));
|
||||
vrfy(log2(0.5) == -1,
|
||||
strcat(str(tnum++), ': log2(0.5) == -1'));
|
||||
vrfy(log2(0.5) == -1,
|
||||
strcat(str(tnum++), ': log2(0.5) == -1'));
|
||||
vrfy(log2(0.5) == log2(0.5),
|
||||
strcat(str(tnum++), ': log2(0.5) == log2(0.5)'));
|
||||
vrfy(0^0 == 1,
|
||||
strcat(str(tnum++), ': 0^0 == 1'));
|
||||
vrfy(1^0 == 1,
|
||||
strcat(str(tnum++), ': 1^0 == 1'));
|
||||
vrfy(1^1 == 1,
|
||||
strcat(str(tnum++), ': 1^1 == 1'));
|
||||
vrfy(2^0 == 1,
|
||||
strcat(str(tnum++), ': 2^0 == 1'));
|
||||
vrfy(log2(1) == 0,
|
||||
strcat(str(tnum++), ': log2(1) == 0'));
|
||||
vrfy(log2(1.0) == 0,
|
||||
strcat(str(tnum++), ': log2(1.0) == 0'));
|
||||
vrfy(log2(2) == 1,
|
||||
strcat(str(tnum++), ': log2(2) == 1'));
|
||||
vrfy(log2(4) == 2,
|
||||
@@ -4879,8 +4897,9 @@ define test_charset()
|
||||
vrfy("\123" == char(0123), '4706: "\\123" == char(0123)');
|
||||
vrfy("\123\124" == "ST", '4707: "\\123\\124" == "ST"');
|
||||
vrfy("\311" == char(201), '4708: "\\311" == char(201)');
|
||||
vrfy("\119" == "\t9", '4709: "\\119" == "\t9"');
|
||||
vrfy("\765" == "\365", '4710: "\\765" == "\365"');
|
||||
/* NOTE: We skip non-ASCII to avoid problems with old awk that cannot handle them */
|
||||
/* vrfy("\119" == "\t9", '4709: "\\119" == "\t9"'); */
|
||||
/* vrfy("\765" == "\365", '4710: "\\765" == "\365"'); */
|
||||
vrfy("\x61" == "a", '4711: "\\x61" == "a"');
|
||||
vrfy("\x73" == "s", '4712: "\\x73" == "s"');
|
||||
vrfy("\xea" == char(234), '4713: "\\xea" == char(234)');
|
||||
@@ -7897,7 +7916,7 @@ print '180: define g7500e(a,b) = *a = b'
|
||||
*/
|
||||
define test_ptr()
|
||||
{
|
||||
local a, b, c, A, B, B1, B2, M, L, p, q, p0, q0;
|
||||
local a, b, c, A, B, B1, B2, M, L, p, q, r, p0, q0;
|
||||
|
||||
print '7500: Beginning test_ptr';
|
||||
|
||||
@@ -8023,22 +8042,21 @@ define test_ptr()
|
||||
p = &M[0], *p = 5;
|
||||
print '7587: p = &M[0], *p = 5;';
|
||||
vrfy(M[0] == 5, '7588: M[0] == 5');
|
||||
*++p = 6;
|
||||
print '7589: *++p = 6;';
|
||||
vrfy(M[1] == 6, '7590: M[1] == 6');
|
||||
q = p++;
|
||||
print '7591: q = p++;';
|
||||
q = &M[1], *q = 6;
|
||||
print '7589: q = &M[1], *q = 6;';
|
||||
vrfy(M[1] == 6, '7588: M[1] == 6');
|
||||
vrfy(M[0] == 5, '7588: M[0] == 5');
|
||||
vrfy(q == &M[1], '7592: q == &M[1]');
|
||||
vrfy(p == &M[2], '7593: p == &M[2]');
|
||||
vrfy(p == &M[0], '7593: p == &M[0]');
|
||||
quomod(17,5,*q,*p);
|
||||
print '7594: quomod(17,5,*p,*q);';
|
||||
vrfy(M[1] == 3 && M[2] == 2, '7595: M[1] == 3 && M[2] == 2');
|
||||
vrfy(M[1] == 3 && M[0] == 2, '7595: M[1] == 3 && M[0] == 2');
|
||||
swap(*p, *q);
|
||||
print '7596: swap(*p, *q);';
|
||||
vrfy(M[1] == 2 && M[2] == 3, '7597: M[1] == 2 && M[2] == 3');
|
||||
vrfy(M[1] == 2 && M[0] == 3, '7597: M[1] == 2 && M[0] == 3');
|
||||
A = *M = {7,8};
|
||||
print '7598: A = *M = {7,8};';
|
||||
vrfy(M == (mat[4] = {5,2,3,4}), '7599: M == (mat[4] = {5,2,3,4})');
|
||||
vrfy(M == (mat[4] = {3,2,3,4}), '7599: M == (mat[4] = {3,2,3,4})');
|
||||
vrfy(A == (mat[4] = {7,8,3,4}), '7600: A == (mat[4] = {7,8,3,4})');
|
||||
|
||||
/* Values which point to themselves */
|
||||
@@ -8050,46 +8068,64 @@ define test_ptr()
|
||||
print '7603: A = &B, B = &A;';
|
||||
vrfy(**A == A && ***A == B, '7604: **A == A && ***A == B');
|
||||
|
||||
/* Testing functions that return pointers */
|
||||
/* verify arithmetic value address operation restrictions */
|
||||
|
||||
M[3] = 7;
|
||||
print '7605: M[3] = 7;';
|
||||
vrfy(*g7500b(&M[1], 2) == 7, '7606: *g7500b(&M[1], 2) == 7');
|
||||
|
||||
*g7500b(&M[1], 2) = 8;
|
||||
print '7607: *g7500b(&M[1], 2) = 8;';
|
||||
vrfy(M[3] == 8, '7608: M[3] == 8');
|
||||
M[3] = list(9,10);
|
||||
print '7609: M[3] = list(9,10);';
|
||||
vrfy((*g7500b(&M[1], 2))[[1]] == 10,
|
||||
'7610: (*g7500b(&M[1], 2))[[1]] == 10');
|
||||
M = mat[10] = {0,1,2,3,4,5,6,7,8,9};
|
||||
print '7605: M = mat[10] = {0,1,2,3,4,5,6,7,8,9};';
|
||||
/* NOTE: The next set of tests will trigger 10 errors by design */
|
||||
ecnt += 10;
|
||||
print '7606: ecnt += 10';
|
||||
p = &M[3];
|
||||
print '7607: p = &M[3]';
|
||||
++p;
|
||||
print '7608: ++p';
|
||||
vrfy(p == error("E_INVALID_ADDR_OP"),
|
||||
'7609: p == error("E_INVALID_ADDR_OP")');
|
||||
p = &M[4];
|
||||
print '7610: p = &M[4]';
|
||||
p++;
|
||||
print '7611: p++';
|
||||
vrfy(p == error("E_INVALID_ADDR_OP"),
|
||||
'7612: p == error("E_INVALID_ADDR_OP")');
|
||||
p = &M[5];
|
||||
print '7613: p = &M[5]';
|
||||
q = &M[8];
|
||||
print '7614: q = &M[8]';
|
||||
vrfy(q+5 == error("E_INVALID_ADDR_OP"),
|
||||
'7615: q+5 == error("E_INVALID_ADDR_OP")');
|
||||
vrfy(q-7 == error("E_INVALID_ADDR_OP"),
|
||||
'7616: q-7 == error("E_INVALID_ADDR_OP")');
|
||||
vrfy(p+q == error("E_INVALID_ADDR_OP"),
|
||||
'7617: p+q == error("E_INVALID_ADDR_OP")');
|
||||
r = p-q;
|
||||
print '7618: r = p-q;';
|
||||
|
||||
/* Testing number and string pointers */
|
||||
|
||||
a = 24, b = 4 * 6, c = 4!;
|
||||
print '7611: a = 24, b = 4 * 6, c= 4!;';
|
||||
vrfy(isptr(&*a) == 4, '7612: isptr(&*a) == 4');
|
||||
vrfy(&*a == &24, '7613: &*a == &24');
|
||||
vrfy(&*a == &*b, '7614: &*a == &*b');
|
||||
vrfy(&*a != &*c, '7615: &*a != &*c');
|
||||
print '7619: a = 24, b = 4 * 6, c= 4!;';
|
||||
vrfy(isptr(&*a) == 4, '7620: isptr(&*a) == 4');
|
||||
vrfy(&*a == &24, '7621: &*a == &24');
|
||||
vrfy(&*a == &*b, '7622: &*a == &*b');
|
||||
vrfy(&*a != &*c, '7623: &*a != &*c');
|
||||
|
||||
a = b = "abc", c = strcat("a", "bc");
|
||||
print '7616: a = b = "abc", c = strcat("a", "bc");';
|
||||
vrfy(isptr(&*a) == 3, '7617: isptr(&*a) == 3');
|
||||
vrfy(&*a == &"abc", '7618: &*a == &"abc"');
|
||||
vrfy(&*a == &*b, '7619: &*a == &*b');
|
||||
vrfy(&*a != &*c, '7620: &*a != &*c');
|
||||
print '7624: a = b = "abc", c = strcat("a", "bc");';
|
||||
vrfy(isptr(&*a) == 3, '7625: isptr(&*a) == 3');
|
||||
vrfy(&*a == &"abc", '7626: &*a == &"abc"');
|
||||
vrfy(&*a == &*b, '7627: &*a == &*b');
|
||||
vrfy(&*a != &*c, '7628: &*a != &*c');
|
||||
a = c;
|
||||
print '7621: a = c;';
|
||||
vrfy(&*a == &*c, '7622: &*a == &*c');
|
||||
print '7629: a = c;';
|
||||
vrfy(&*a == &*c, '7630: &*a == &*c');
|
||||
|
||||
/* Verifying null-ness of freed numbers */
|
||||
|
||||
c = 4!, p = &*c, free(c);
|
||||
print '7623: c = 4!, p = &*c, free(c)';
|
||||
vrfy(isnull(*p), '7624: isnull(*p)');
|
||||
print '7631: c = 4!, p = &*c, free(c)';
|
||||
vrfy(isnull(*p), '7632: isnull(*p)');
|
||||
|
||||
print '7625: Ending test_ptr';
|
||||
print '7633: Ending test_ptr';
|
||||
}
|
||||
print '181: parsed test_ptr()';
|
||||
|
||||
@@ -8191,7 +8227,8 @@ define test_newstring()
|
||||
vrfy(A == "A\255gdef", '7761: A == "A\\255gdef"');
|
||||
setbit(A, 16, 0);
|
||||
print '7762: setbit(A, 16, 0);';
|
||||
vrfy(A == "A\255fdef", '7763: A == "A\255fdef"');
|
||||
/* NOTE: We skip non-ASCII to avoid problems with old awk that cannot handle them */
|
||||
/* vrfy(A == "A\255fdef", '7763: A == "A\255fdef"'); */
|
||||
|
||||
q = "curds" " and " "whey";
|
||||
print '7764: q = "curds" " and " "whey"';
|
||||
@@ -9145,8 +9182,8 @@ read -once "test8900.special";
|
||||
print '8902: about to run test8900(1,,8903)';
|
||||
testnum = test8900(1,,8903);
|
||||
print "8941: ecnt ==", ecnt;
|
||||
print '8942: ecnt = 214;'
|
||||
ecnt = 214;
|
||||
print '8942: ecnt = 224;'
|
||||
ecnt = 224;
|
||||
|
||||
|
||||
/*
|
||||
|
4
calc.c
4
calc.c
@@ -543,8 +543,8 @@ main(int argc, char **argv)
|
||||
cmdbuf[cmdlen++] = '\n';
|
||||
cmdbuf[cmdlen] = '\0';
|
||||
if (p_flag != true) {
|
||||
if (fclose(stdin)) {
|
||||
perror("main(): fclose(stdin) failed:");
|
||||
if (freopen("/dev/null", "r", stdin) == NULL) {
|
||||
perror("in main: freopen(\"/dev/null\", \"r\", stdin) failed:");
|
||||
}
|
||||
stdin_closed = true;
|
||||
}
|
||||
|
93
calc.man
93
calc.man
@@ -470,6 +470,24 @@ The
|
||||
flag overrides
|
||||
.BR \-i .
|
||||
|
||||
.sp 1
|
||||
When running calc as a shell script (see
|
||||
.B "SHELL SCRIPT MODE"
|
||||
for details), calc will close standard input (stdin)
|
||||
during startup
|
||||
.B UNLESS
|
||||
the
|
||||
.B \-p
|
||||
flag is given on the command line.
|
||||
When calc is running in
|
||||
.BR "shell script mode" ,
|
||||
shell scripts that call the
|
||||
.BR prompt (str)
|
||||
builtin will not work properly (the prompt builtin
|
||||
will always fail) unless the
|
||||
.B \-p
|
||||
flag is given on the command line.
|
||||
|
||||
.TP
|
||||
.B \-q
|
||||
Disable the reading of the startup scripts.
|
||||
@@ -501,7 +519,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 +561,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.
|
||||
@@ -651,7 +669,9 @@ echo chongo was here | calc \-i 'print fgetline(files(0));'
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
This is because without \-p, the interactive parser, in an effort
|
||||
This is because without
|
||||
.BR \-p ,
|
||||
the interactive parser, in an effort
|
||||
to parse interactive commands, flushes data on standard input.
|
||||
|
||||
.PP
|
||||
@@ -804,7 +824,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
|
||||
@@ -932,6 +952,67 @@ whereas
|
||||
.sp 1
|
||||
will not.
|
||||
|
||||
.sp 1
|
||||
By default, using calc startup in
|
||||
.BR "shell script mode" ,
|
||||
calc will close standard input (stdin).
|
||||
Thus builtin functions such as
|
||||
.BR prompt (str)
|
||||
will fail (return a null value).
|
||||
Calc shell scripts that call the
|
||||
.BR prompt (str)
|
||||
builtin will not work properly (the prompt builtin
|
||||
will always fail and return a null value) unless the
|
||||
.B \-p
|
||||
flag is given on the command line.
|
||||
|
||||
.sp 1
|
||||
The following shell script will always print "got null" because
|
||||
stdin will be closed by calc during startup:
|
||||
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
#!/usr/bin/calc \-q \-f
|
||||
|
||||
# The prompt will ALWAYS FAIL and return a null value
|
||||
n = prompt("Test> ");
|
||||
if (isnull(n)) {
|
||||
print("got null");
|
||||
} else {
|
||||
print("got " + n);
|
||||
}
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
However the following shell script (note the
|
||||
.B \-p
|
||||
before the
|
||||
.B \-f
|
||||
in the 1st line) will be interactive, prompt with "Test> " and print
|
||||
the "got" result as expected:
|
||||
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
#!/usr/bin/calc \-q \-p \-f
|
||||
|
||||
n = prompt("Test> ");
|
||||
if (isnull(n)) {
|
||||
print("got null");
|
||||
} else {
|
||||
print("got " + n);
|
||||
}
|
||||
.fi
|
||||
.in -5n
|
||||
|
||||
.sp 1
|
||||
Note in the example above, the
|
||||
.B \-p
|
||||
flag must be given before the final
|
||||
.B \-f
|
||||
command line flag.
|
||||
|
||||
.PP
|
||||
|
||||
.SH DATA TYPES
|
||||
@@ -973,7 +1054,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
|
||||
@@ -1431,7 +1512,7 @@ the following GitHub repo:
|
||||
https://github.com/lcn2/calc
|
||||
.in -0.5i
|
||||
.sp
|
||||
The very latest calc souece is found at the top master branch.
|
||||
The very latest calc source is found at the top master branch.
|
||||
|
||||
.PP
|
||||
|
||||
|
350
chk_tree
Executable file
350
chk_tree
Executable file
@@ -0,0 +1,350 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# chk_tree - verify that the source tree and git and Makefiles are in sync
|
||||
#
|
||||
# This tools is used by "make prep".
|
||||
#
|
||||
# Copyright (C) 2023 Landon Curt Noll
|
||||
#
|
||||
# Calc is open software; you can redistribute it and/or modify it under
|
||||
# the terms of version 2.1 of the GNU Lesser General Public License
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# Calc is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
# Public License for more details.
|
||||
#
|
||||
# A copy of version 2.1 of the GNU Lesser General Public License is
|
||||
# distributed with calc under the filename COPYING-LGPL. You should have
|
||||
# received a copy with calc; if not, write to Free Software Foundation, Inc.
|
||||
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# Under source code control: 2023/10/04 21:04:44
|
||||
# File existed as early as: 2023
|
||||
#
|
||||
# chongo <was here> /\oo/\ http://www.isthe.com/chongo/
|
||||
# Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
||||
|
||||
# setup
|
||||
#
|
||||
EXIT_CODE=0
|
||||
|
||||
# firewall - verify that the "make distdir" directories exist
|
||||
#
|
||||
make distdir >/dev/null 2>&1
|
||||
status="$?"
|
||||
if [[ $status -ne 0 ]]; then
|
||||
echo "$0: ERROR: make distdir exit code: $status" 1>&2
|
||||
EXIT_CODE=10
|
||||
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
|
||||
fi
|
||||
|
||||
# collect make distdir directory list
|
||||
#
|
||||
# We ignore make action lines.
|
||||
#
|
||||
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
|
||||
#
|
||||
# We ignore NOTES because it contains notes that are not part of calc source.
|
||||
# We ignore .git and GitHub because they are not part of the calc source tarball.
|
||||
#
|
||||
declare -a FINDDIR
|
||||
mapfile -t FINDDIR < <(find . -type d \
|
||||
! -path './NOTES/*' ! -name NOTES \
|
||||
! -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
|
||||
#
|
||||
declare -a DIFF_DISTDIR_FINDDIR
|
||||
mapfile -t DIFF_DISTDIR_FINDDIR < <(printf '%s\n' "${DISTDIR[@]}" "${FINDDIR[@]}" |
|
||||
tr ' ' '\n' | sort | uniq -u)
|
||||
if [[ ${#DIFF_DISTDIR_FINDDIR[@]} -ne 0 ]]; then
|
||||
|
||||
# report that DISTDIR and FINDDIR differ
|
||||
#
|
||||
echo "$0: ERROR: distdir and find dir differ for critical directories" 1>&2
|
||||
declare -a ONLY_FINDDIR
|
||||
mapfile -t ONLY_FINDDIR < <(printf '%s\n' "${DISTDIR[@]}" "${DISTDIR[@]}" "${FINDDIR[@]}" |
|
||||
tr ' ' '\n' | sort | uniq -u)
|
||||
if [[ ${#ONLY_FINDDIR[@]} -ne 0 ]]; then
|
||||
echo "$0: ERROR: found only in find dir: ${ONLY_FINDDIR[*]}" 1>&2
|
||||
fi
|
||||
declare -a ONLY_DISTDIR
|
||||
mapfile -t ONLY_DISTDIR < <(printf '%s\n' "${FINDDIR[@]}" "${FINDDIR[@]}" "${DISTDIR[@]}" |
|
||||
tr ' ' '\n' | sort | uniq -u)
|
||||
if [[ ${#ONLY_DISTDIR[@]} -ne 0 ]]; then
|
||||
echo "$0: ERROR: found only in distdir: ${ONLY_DISTDIR[*]}" 1>&2
|
||||
fi
|
||||
EXIT_CODE=13
|
||||
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
|
||||
fi
|
||||
|
||||
# firewall - verify that the "make distlist" files exist
|
||||
#
|
||||
make distlist >/dev/null 2>&1
|
||||
status="$?"
|
||||
if [[ $status -ne 0 ]]; then
|
||||
echo "$0: ERROR: make distlist exit code: $status" 1>&2
|
||||
EXIT_CODE=14
|
||||
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
|
||||
fi
|
||||
|
||||
# collect make distlist file list
|
||||
#
|
||||
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"
|
||||
done
|
||||
|
||||
# case: under git control
|
||||
#
|
||||
if [[ -d .git ]]; then
|
||||
|
||||
# obtain the list of files under git
|
||||
#
|
||||
# We ignore .git and GitHub related files because they are not part of the calc source tarball.
|
||||
#
|
||||
declare -a GITLS
|
||||
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
|
||||
#
|
||||
declare -a DIFF_DISTLIST_GITLS
|
||||
mapfile -t DIFF_DISTLIST_GITLS < <(printf '%s\n' "${DISTLIST[@]}" "${GITLS[@]}" |
|
||||
tr ' ' '\n' | sort | uniq -u)
|
||||
if [[ ${#DIFF_DISTLIST_GITLS[@]} -ne 0 ]]; then
|
||||
|
||||
# report that DISTLIST and GITLS differ
|
||||
#
|
||||
echo "$0: ERROR: distlist and git ls differ for critical files" 1>&2
|
||||
declare -a ONLY_GITLS
|
||||
mapfile -t ONLY_GITLS < <(printf '%s\n' "${DISTLIST[@]}" "${DISTLIST[@]}" "${GITLS[@]}" |
|
||||
tr ' ' '\n' | sort | uniq -u)
|
||||
if [[ ${#ONLY_GITLS[@]} -ne 0 ]]; then
|
||||
echo "$0: ERROR: found only in git ls: ${ONLY_GITLS[*]}" 1>&2
|
||||
fi
|
||||
declare -a ONLY_DISTLIST
|
||||
mapfile -t ONLY_DISTLIST < <(printf '%s\n' "${GITLS[@]}" "${GITLS[@]}" "${DISTLIST[@]}" |
|
||||
tr ' ' '\n' | sort | uniq -u)
|
||||
if [[ ${#ONLY_DISTLIST[@]} -ne 0 ]]; then
|
||||
echo "$0: ERROR: found only in distlist: ${ONLY_DISTLIST[*]}" 1>&2
|
||||
fi
|
||||
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
|
||||
|
||||
# collect make buildlist file list
|
||||
#
|
||||
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"
|
||||
done
|
||||
|
||||
# look for something in DISTLIST that is also in BUILDLIST
|
||||
#
|
||||
# The BUILDLIST are a set of files that are result of building calc
|
||||
# and thus should NOT be part of the DISTLIST (list of files used
|
||||
# to form the calc source distribtion).
|
||||
#
|
||||
declare -a DISTLIST_ALSO_IN_BUILDLIST
|
||||
mapfile -t DISTLIST_ALSO_IN_BUILDLIST < <(
|
||||
for i in "${DISTLIST_A[@]}"; do
|
||||
if [[ -n "${BUILDLIST_A[$i]}" ]]; then
|
||||
echo "$i";
|
||||
fi
|
||||
done
|
||||
)
|
||||
if [[ ${#DISTLIST_ALSO_IN_BUILDLIST[@]} -ne 0 ]]; then
|
||||
|
||||
# report that something in DISTLIST was found in BUILDLIST
|
||||
#
|
||||
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=25
|
||||
echo "$0: Warning: set EXIT_CODE: $EXIT_CODE" 1>&2
|
||||
fi
|
||||
|
||||
# collect list of files
|
||||
#
|
||||
# We ignore NOTES because it contains notes that are not part of calc source.
|
||||
# We ignore .git and GitHub because they are not part of the calc source tarball.
|
||||
# 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 \
|
||||
! -path './NOTES/*' ! -name NOTES \
|
||||
! -path './.git/*' ! -name .git \
|
||||
! -path './.github/*' ! -name .github \
|
||||
! -name 'CODE_OF_CONDUCT.md' ! -name 'CONTRIBUTING.md' ! -name '.gitignore' ! -name 'SECURITY.md' \
|
||||
! -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
|
||||
#
|
||||
# We look for a file that is neither a file that neither a result of building calc,
|
||||
# nor part of the calc distribution list in a file list.
|
||||
#
|
||||
# NOTE that the file list has already excluded certain files (see previous section).
|
||||
#
|
||||
# We flag any file in the list that is neither a result of building calc,
|
||||
# nor part of the calc distribution list in a file list.
|
||||
#
|
||||
declare -a UNKNOWN_FILE
|
||||
mapfile -t UNKNOWN_FILE < <(
|
||||
for i in "${FINDFILE[@]}"; do
|
||||
|
||||
# skip if this is a file that is result of building calc
|
||||
#
|
||||
if [[ -n ${BUILDLIST_A["$i"]} ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# skip if this is a file that is calc distribution list
|
||||
#
|
||||
if [[ -n ${DISTLIST_A["$i"]} ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# print the file of unknown status
|
||||
#
|
||||
echo "$i"
|
||||
done
|
||||
)
|
||||
if [[ ${#UNKNOWN_FILE[@]} -ne 0 ]]; then
|
||||
|
||||
# report that something in DISTLIST was found in BUILDLIST
|
||||
#
|
||||
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=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
|
||||
|
||||
# All Done!!! -- Jessica Noll, Age 2
|
||||
#
|
||||
if [[ $EXIT_CODE -ne 0 ]]; then
|
||||
echo "$0: Warning: about to exit $EXIT_CODE" 1>&2
|
||||
fi
|
||||
exit "$EXIT_CODE"
|
36
codegen.c
36
codegen.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* codegen - module to generate opcodes from the input tokens
|
||||
*
|
||||
* Copyright (C) 1999-2007,2017,2021-2023 David I. Bell and Ernest Bowen
|
||||
* Copyright (C) 1999-2007,2017,2021-2023,2025 David I. Bell and Ernest Bowen
|
||||
*
|
||||
* Primary author: David I. Bell
|
||||
*
|
||||
@@ -2425,6 +2425,40 @@ getfilename(char *name, size_t namelen, bool *once)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Useful routine to return the index of one string within another one
|
||||
* which has the format: "str1\000str2\000str3\000...strn\0\0". Index starts
|
||||
* at one for the first string. Returns zero if the string being checked
|
||||
* is not contained in the formatted string.
|
||||
*
|
||||
* Be sure to use \000 instead of \0. ANSI-C compilers interpret "foo\0foo..."
|
||||
* as "foo\017oo...".
|
||||
*
|
||||
* given:
|
||||
* format string formatted into substrings
|
||||
* test string to be found in formatted string
|
||||
*/
|
||||
S_FUNC long
|
||||
stringindex(char *format, char *test)
|
||||
{
|
||||
long index; /* found index */
|
||||
size_t len; /* length of current piece of string */
|
||||
size_t testlen; /* length of test string */
|
||||
|
||||
testlen = strlen(test);
|
||||
index = 1;
|
||||
while (*format) {
|
||||
len = strlen(format);
|
||||
if ((len == testlen) && (*format == *test) &&
|
||||
(strcmp(format, test) == 0))
|
||||
return index;
|
||||
format += (len + 1);
|
||||
index++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read the show command to display useful information
|
||||
*/
|
||||
|
@@ -142,6 +142,12 @@ DISTLIST= ${SCRIPT_SRC} ${MAKE_FILE} README.src
|
||||
#
|
||||
CALCLIBLIST=
|
||||
|
||||
# complete list of files that may be created as part of the build process
|
||||
#
|
||||
# Used by chk_tree via make prep
|
||||
#
|
||||
BUILD_ALL= ${SCRIPT} README
|
||||
|
||||
# complete list of targets
|
||||
#
|
||||
# NOTE: This list MUST be coordinated with the ${CSCRIPT_TARGETS} variable
|
||||
@@ -149,10 +155,11 @@ CALCLIBLIST=
|
||||
#
|
||||
CSCRIPT_TARGETS= ${SCRIPT}
|
||||
TARGETS= ${CSCRIPT_TARGETS} README
|
||||
#
|
||||
|
||||
# rules that are not also names of files
|
||||
#
|
||||
PHONY= all clobber distlist install
|
||||
PHONY= all distlist buildlist distdir calcliblist detaillist depend \
|
||||
echo_inst_files clean clobber install uninstall
|
||||
|
||||
|
||||
############################################################
|
||||
@@ -206,6 +213,13 @@ distlist: ${DISTLIST}
|
||||
fi; \
|
||||
done | LANG=C ${SORT}
|
||||
|
||||
buildlist:
|
||||
${Q} for i in ${BUILD_ALL} /dev/null; do \
|
||||
if [ X"$$i" != X"/dev/null" ]; then \
|
||||
echo cscript/$$i; \
|
||||
fi; \
|
||||
done | fgrep -v '.bak' | LANG=C ${SORT}
|
||||
|
||||
distdir:
|
||||
${Q} echo cscript
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# custom - makefile for calc custom routines
|
||||
#
|
||||
# Copyright (C) 1999-2006,2014,2017-2018,2021,2023 Landon Curt Noll
|
||||
# Copyright (C) 1999-2006,2014,2017-2018,2021,2023,2025 Landon Curt Noll
|
||||
#
|
||||
# Suggestion: Read the ../HOWTO.INSTALL file.
|
||||
#
|
||||
@@ -215,10 +215,23 @@ CALC_DYNAMIC_LIBCUSTCALC= libcustcalc${LIB_EXT_VERSION}
|
||||
#
|
||||
CALC_STATIC_LIBCUSTCALC= libcustcalc.a
|
||||
|
||||
# complete list of files that may be created as part of the build process
|
||||
#
|
||||
# Used by chk_tree via make prep
|
||||
#
|
||||
BUILD_ALL= ${REQUIRED_OBJ} ${CUSTOM_OBJ} \
|
||||
${CALC_DYNAMIC_LIBCUSTCALC} ${CALC_STATIC_LIBCUSTCALC} \
|
||||
.all
|
||||
|
||||
# complete list of targets
|
||||
#
|
||||
TARGETS= ${BLD_TYPE}
|
||||
|
||||
# rules that are not also names of files
|
||||
#
|
||||
PHONY= all distlist buildlist distdir calcliblist depend echo_inst_files clean \
|
||||
clobber install uninstall
|
||||
|
||||
|
||||
############################################################
|
||||
# Allow Makefile.local to change any of the above settings #
|
||||
@@ -238,6 +251,8 @@ all: ${TARGETS} ${INSTALL_H_SRC} ${CUSTOM_CALC_FILES} \
|
||||
# additional Makefile targets #
|
||||
###############################
|
||||
|
||||
.PHONY: ${PHONY}
|
||||
|
||||
calc-dynamic-only: ${CUSTCALC_OBJ} ${CALC_DYNAMIC_LIBCUSTCALC}
|
||||
|
||||
calc-static-only: ${CUSTCALC_OBJ} ${CALC_STATIC_LIBCUSTCALC}
|
||||
@@ -295,6 +310,13 @@ distlist: ${DISTLIST}
|
||||
fi; \
|
||||
done
|
||||
|
||||
buildlist:
|
||||
${Q} for i in ${BUILD_ALL} /dev/null; do \
|
||||
if [ X"$$i" != X"/dev/null" ]; then \
|
||||
echo custom/$$i; \
|
||||
fi; \
|
||||
done | fgrep -v '.bak' | LANG=C ${SORT}
|
||||
|
||||
distdir:
|
||||
${Q} echo custom
|
||||
|
||||
@@ -706,7 +728,6 @@ c_argv.o: ../hash.h
|
||||
c_argv.o: ../have_ban_pragma.h
|
||||
c_argv.o: ../have_const.h
|
||||
c_argv.o: ../have_limits.h
|
||||
c_argv.o: ../have_memmv.h
|
||||
c_argv.o: ../have_newstr.h
|
||||
c_argv.o: ../have_stdbool.h
|
||||
c_argv.o: ../have_stdlib.h
|
||||
@@ -739,7 +760,6 @@ c_devnull.o: ../hash.h
|
||||
c_devnull.o: ../have_ban_pragma.h
|
||||
c_devnull.o: ../have_const.h
|
||||
c_devnull.o: ../have_limits.h
|
||||
c_devnull.o: ../have_memmv.h
|
||||
c_devnull.o: ../have_newstr.h
|
||||
c_devnull.o: ../have_stdbool.h
|
||||
c_devnull.o: ../have_stdlib.h
|
||||
@@ -773,7 +793,6 @@ c_help.o: ../hash.h
|
||||
c_help.o: ../have_ban_pragma.h
|
||||
c_help.o: ../have_const.h
|
||||
c_help.o: ../have_limits.h
|
||||
c_help.o: ../have_memmv.h
|
||||
c_help.o: ../have_newstr.h
|
||||
c_help.o: ../have_stdbool.h
|
||||
c_help.o: ../have_stdlib.h
|
||||
@@ -807,7 +826,6 @@ c_pmodm127.o: ../hash.h
|
||||
c_pmodm127.o: ../have_ban_pragma.h
|
||||
c_pmodm127.o: ../have_const.h
|
||||
c_pmodm127.o: ../have_limits.h
|
||||
c_pmodm127.o: ../have_memmv.h
|
||||
c_pmodm127.o: ../have_newstr.h
|
||||
c_pmodm127.o: ../have_stdbool.h
|
||||
c_pmodm127.o: ../have_stdlib.h
|
||||
@@ -840,7 +858,6 @@ c_pzasusb8.o: ../hash.h
|
||||
c_pzasusb8.o: ../have_ban_pragma.h
|
||||
c_pzasusb8.o: ../have_const.h
|
||||
c_pzasusb8.o: ../have_limits.h
|
||||
c_pzasusb8.o: ../have_memmv.h
|
||||
c_pzasusb8.o: ../have_newstr.h
|
||||
c_pzasusb8.o: ../have_stdbool.h
|
||||
c_pzasusb8.o: ../have_stdlib.h
|
||||
@@ -874,7 +891,6 @@ c_register.o: ../hash.h
|
||||
c_register.o: ../have_ban_pragma.h
|
||||
c_register.o: ../have_const.h
|
||||
c_register.o: ../have_limits.h
|
||||
c_register.o: ../have_memmv.h
|
||||
c_register.o: ../have_newstr.h
|
||||
c_register.o: ../have_stdbool.h
|
||||
c_register.o: ../have_stdlib.h
|
||||
@@ -910,7 +926,6 @@ c_sysinfo.o: ../hash.h
|
||||
c_sysinfo.o: ../have_ban_pragma.h
|
||||
c_sysinfo.o: ../have_const.h
|
||||
c_sysinfo.o: ../have_limits.h
|
||||
c_sysinfo.o: ../have_memmv.h
|
||||
c_sysinfo.o: ../have_newstr.h
|
||||
c_sysinfo.o: ../have_stdbool.h
|
||||
c_sysinfo.o: ../have_stdlib.h
|
||||
@@ -948,7 +963,6 @@ custtbl.o: ../hash.h
|
||||
custtbl.o: ../have_ban_pragma.h
|
||||
custtbl.o: ../have_const.h
|
||||
custtbl.o: ../have_limits.h
|
||||
custtbl.o: ../have_memmv.h
|
||||
custtbl.o: ../have_newstr.h
|
||||
custtbl.o: ../have_stdbool.h
|
||||
custtbl.o: ../have_stdlib.h
|
||||
|
10
errtbl.c
10
errtbl.c
@@ -759,6 +759,8 @@ CONST struct errtbl error_table[] =
|
||||
{ 10607, "E_LOG_5", "Cannot calculate log of 0" },
|
||||
{ 10608, "E_LOG2_4", "Cannot calculate log base 2 of 0" },
|
||||
{ 10609, "E_LOGN_6", "Cannot calculate log base n of 0" },
|
||||
{ 10610, "E_INVALID_DEREF", "Dereferencing a non-variable" },
|
||||
{ 10611, "E_INVALID_ADDR_OP", "Invalid arithmetic address operation" },
|
||||
/* IMPORTANT NOTE: add new entries above here and be sure their errnum numeric value is consecutive! */
|
||||
|
||||
/* The next NULL entry must be last */
|
||||
@@ -855,7 +857,7 @@ is_e_digits(CONST char *errsym)
|
||||
* check for only digits remaining
|
||||
*/
|
||||
for (p = errsym+2; *p != '\0'; ++p) {
|
||||
if (!isascii(*p) || !isdigit(*p)) {
|
||||
if (!isascii((int)*p) || !isdigit((int)*p)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1090,7 +1092,7 @@ is_e_1string(CONST char *errsym)
|
||||
* must match regular expression: ^E_[A-Z][A-Z0-9_]+$
|
||||
*/
|
||||
for (p = errsym+3; *p != '\0'; ++p) {
|
||||
if (!isascii(*p) || !(isupper(*p) || isdigit(*p) || *p == '_')) {
|
||||
if (!isascii((int)*p) || !(isupper((int)*p) || isdigit((int)*p) || *p == '_')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2183,8 +2185,8 @@ print_errsym(void)
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
extern char *optarg; /* argv index of the next arg */
|
||||
extern int optind; /* argv index of the next arg */
|
||||
EXTERN char *optarg; /* argv index of the next arg */
|
||||
EXTERN int optind; /* argv index of the next arg */
|
||||
int e_flag = 0; /* 1 ==> -e flag was used */
|
||||
int d_flag = 0; /* 1 ==> -s flag was used */
|
||||
int i;
|
||||
|
2
file.c
2
file.c
@@ -1387,7 +1387,7 @@ filepos2z(FILEPOS pos)
|
||||
ret.len = FILEPOS_BITS/BASEB;
|
||||
ret.v = alloc(ret.len);
|
||||
zclearval(ret);
|
||||
SWAP_HALF_IN_FILEPOS(ret.v, &pos);
|
||||
SWAP_HALF_IN_FILEPOS(ret.v, (HALF *)&pos);
|
||||
ret.sign = 0;
|
||||
ztrim(&ret);
|
||||
|
||||
|
16
fposval.c
16
fposval.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* fposval - Determine information about the file position type
|
||||
*
|
||||
* Copyright (C) 1999,2021,2023 Landon Curt Noll
|
||||
* Copyright (C) 1999,2021,2023,2025 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -71,7 +71,6 @@
|
||||
#include "have_fpos_pos.h"
|
||||
#include "alloc.h"
|
||||
#include "have_unused.h"
|
||||
#include "have_memmv.h"
|
||||
#include "zmath.h"
|
||||
|
||||
|
||||
@@ -114,15 +113,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",
|
||||
@@ -135,7 +139,7 @@ main(int UNUSED(argc), char **argv)
|
||||
*/
|
||||
#if defined(HAVE_FILEPOS_SCALAR)
|
||||
printf("#define SWAP_HALF_IN_FILEPOS(dest, src) \\\n"
|
||||
"\t(*(dest) = *(src))\n");
|
||||
"\t(*((HALF *)(dest)) = *((HALF *)(src)))\n");
|
||||
#else /* HAVE_FILEPOS_SCALAR */
|
||||
/*
|
||||
* Normally a "(*(dest) = *(src))" would do, but on some
|
||||
|
244
func.c
244
func.c
@@ -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,10 +2620,12 @@ 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);
|
||||
}
|
||||
/* check if division is COMPLEX or NUMBER */
|
||||
/* check for COMPLEX or NUMBER division */
|
||||
if (cisreal(p_cval)) {
|
||||
/* ln(x) / ln(n) was NUMBER, not COMPLEX */
|
||||
result.v_num = c_to_q(p_cval, true);
|
||||
@@ -2594,10 +2642,12 @@ 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);
|
||||
}
|
||||
/* check if division is COMPLEX or NUMBER */
|
||||
/* check for COMPLEX or NUMBER division */
|
||||
if (cisreal(p_cval)) {
|
||||
/* ln(x) / ln(n) was NUMBER, not COMPLEX */
|
||||
result.v_num = c_to_q(p_cval, true);
|
||||
@@ -2620,16 +2670,18 @@ 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);
|
||||
}
|
||||
/* check if division is COMPLEX or NUMBER */
|
||||
/* check for COMPLEX or NUMBER division */
|
||||
if (cisreal(p_cval)) {
|
||||
/* ln(x) / ln(n) was NUMBER, not COMPLEX */
|
||||
result.v_num = c_to_q(p_cval, true);
|
||||
result.v_type = V_NUM;
|
||||
} else {
|
||||
/* ln(x) / ln(n) is COMPLEX */
|
||||
/* ln(x) / ln(n) is COMPLEX result */
|
||||
result.v_type = V_COM;
|
||||
result.v_com = p_cval;
|
||||
}
|
||||
@@ -2640,10 +2692,12 @@ 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);
|
||||
}
|
||||
/* ln(x) / ln(n) is NUMBER */
|
||||
/* ln(x) / ln(n) is NUMBER result */
|
||||
result.v_type = V_NUM;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
73
have_memmv.c
73
have_memmv.c
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* have_memmv - Determine if we have memmove()
|
||||
*
|
||||
* Copyright (C) 1999,2021 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* Calc is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
* Public License for more details.
|
||||
*
|
||||
* A copy of version 2.1 of the GNU Lesser General Public License is
|
||||
* distributed with calc under the filename COPYING-LGPL. You should have
|
||||
* received a copy with calc; if not, write to Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 1997/04/16 02:02:34
|
||||
* File existed as early as: 1997
|
||||
*
|
||||
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
|
||||
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
||||
*/
|
||||
|
||||
/*
|
||||
* usage:
|
||||
* have_memmv
|
||||
*
|
||||
* Not all systems with memcpy() have memmove() functions, so this may not
|
||||
* compile on your system.
|
||||
*
|
||||
* This prog outputs several defines:
|
||||
*
|
||||
* HAVE_MEMMOVE
|
||||
* defined ==> use memmove()
|
||||
* undefined ==> use internal slow memmove() instead
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "have_string.h"
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "banned.h" /* include after system header <> includes */
|
||||
|
||||
|
||||
#define MOVELEN 3
|
||||
|
||||
char src[] = "chongo was here";
|
||||
char dest[MOVELEN+1];
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
#if defined(HAVE_NO_MEMMOVE)
|
||||
|
||||
printf("#undef HAVE_MEMMOVE /* no */\n");
|
||||
|
||||
#else /* HAVE_NO_MEMMOVE */
|
||||
|
||||
(void) memmove(dest, src, MOVELEN);
|
||||
|
||||
printf("#define HAVE_MEMMOVE /* yes */\n");
|
||||
|
||||
#endif /* HAVE_NO_MEMMOVE */
|
||||
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
}
|
39
help.c
39
help.c
@@ -56,38 +56,41 @@ STATIC struct help_alias {
|
||||
char *topic;
|
||||
char *filename;
|
||||
} halias[] = {
|
||||
/* We sort the list below via: sort -d -u */
|
||||
{"=", "address"},
|
||||
{"->", "arrow"},
|
||||
{"=", "assign"},
|
||||
{"*", "dereference"},
|
||||
{".", "oldvalue"},
|
||||
{"%", "mod"},
|
||||
{"//", "quo"},
|
||||
{".", "oldvalue"},
|
||||
{"#", "pound"},
|
||||
{"calc", "help"},
|
||||
{"//", "quo"},
|
||||
{"COPYING_LGPL", "COPYING-LGPL"},
|
||||
{"COPYLEFT", "copyright"},
|
||||
{"COPYRIGHT", "copyright"},
|
||||
{"Copyleft", "copyright"},
|
||||
{"Copyright", "copyright"},
|
||||
{"abort", "command"},
|
||||
{"cd", "command"},
|
||||
{"copy", "blkcpy"},
|
||||
{"copying", "COPYING"},
|
||||
{"copying-lgpl", "COPYING-LGPL"},
|
||||
{"copying_lgpl", "COPYING-LGPL"},
|
||||
{"COPYING_LGPL", "COPYING-LGPL"},
|
||||
{"Copyright", "copyright"},
|
||||
{"COPYRIGHT", "copyright"},
|
||||
{"Copyleft", "copyright"},
|
||||
{"COPYLEFT", "copyright"},
|
||||
{"define", "command"},
|
||||
{"read", "command"},
|
||||
{"write", "command"},
|
||||
{"quit", "command"},
|
||||
{"exit", "command"},
|
||||
{"abort", "command"},
|
||||
{"cd", "command"},
|
||||
{"show", "command"},
|
||||
{"stdlib", "resource"},
|
||||
{"question", "questions"},
|
||||
{"dm2d", "dms2d"},
|
||||
{"exit", "command"},
|
||||
{"gm2g", "gms2g"},
|
||||
{"hm2d", "hms2d"},
|
||||
{"man", "calc"},
|
||||
{"question", "questions"},
|
||||
{"quit", "command"},
|
||||
{"read", "command"},
|
||||
{"release", "releases"},
|
||||
{"show", "command"},
|
||||
{"stdlib", "resource"},
|
||||
{"usage", "calc"},
|
||||
{"write", "command"},
|
||||
|
||||
/* MUST BE LAST! */
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
104
help/Makefile
104
help/Makefile
@@ -118,76 +118,65 @@ V=@:
|
||||
# Files managed by this Makefile #
|
||||
##################################
|
||||
|
||||
STD_HELP_FILES_1= intro overview help
|
||||
STD_HELP_FILES_1= intro overview
|
||||
BLT_HELP_FILES_1a= calc
|
||||
|
||||
STD_HELP_FILES_2= assoc
|
||||
|
||||
BLT_HELP_FILES_3= builtin man
|
||||
|
||||
STD_HELP_FILES_4= command config custom define environment expression
|
||||
|
||||
BLT_HELP_FILES_3= builtin
|
||||
STD_HELP_FILES_4= command config custom define environment
|
||||
BLT_HELP_FILES_5= errorcodes
|
||||
|
||||
STD_HELP_FILES_6= file history interrupt list mat
|
||||
|
||||
STD_HELP_FILES_6= expression file history interrupt list mat
|
||||
# because obj is built special (due to confusion with it as
|
||||
# a symlink for some built environments, we treat obj specially
|
||||
# and call it obj.file
|
||||
#
|
||||
SPECIAL_HELP_7= obj.file
|
||||
|
||||
STD_HELP_FILES_8= operator statement
|
||||
|
||||
STD_HELP_FILES_8= operator
|
||||
BLT_HELP_FILES_9= resource
|
||||
STD_HELP_FILES_10= script statement types unexpected variable
|
||||
|
||||
STD_HELP_FILES_10= types script
|
||||
|
||||
BLT_HELP_FILES_10a= usage cscript
|
||||
|
||||
STD_HELP_FILES_10b= unexpected variable
|
||||
|
||||
BLT_HELP_FILES_11= bindings custom_cal libcalc new_custom resource
|
||||
BLT_HELP_FILES_11= bindings custom_cal libcalc new_custom cscript
|
||||
|
||||
STD_HELP_FILES_12= archive
|
||||
BLT_HELP_FILES_13= bugs changes contrib
|
||||
STD_HELP_FILES_14= todo wishlist
|
||||
|
||||
BLT_HELP_FILES_13= bugs changes
|
||||
STD_HELP_FILES_15= credit
|
||||
# copyright is printed by help.c is from the Copyright string found in version.c
|
||||
BLT_HELP_FILES_16= COPYING COPYING-LGPL questions releases
|
||||
|
||||
STD_HELP_FILES_14= credit
|
||||
|
||||
BLT_HELP_FILES_14= contrib COPYING COPYING-LGPL questions releases
|
||||
|
||||
STD_HELP_FILES_15= wishlist todo
|
||||
STD_HELP_FILES_17= help
|
||||
|
||||
# These files are used in the following order to construct full
|
||||
#
|
||||
FULL_HELP_FILES= ${STD_HELP_FILES_1} ${STD_HELP_FILES_2} \
|
||||
FULL_HELP_FILES= ${STD_HELP_FILES_1} ${BLT_HELP_FILES_1a} \
|
||||
${STD_HELP_FILES_2} \
|
||||
${BLT_HELP_FILES_3} ${STD_HELP_FILES_4} \
|
||||
${BLT_HELP_FILES_5} ${STD_HELP_FILES_6} \
|
||||
${SPECIAL_HELP_7} ${STD_HELP_FILES_8} \
|
||||
${BLT_HELP_FILES_9} ${STD_HELP_FILES_10} \
|
||||
${BLT_HELP_FILES_10a} ${STD_HELP_FILES_10b} \
|
||||
${BLT_HELP_FILES_11} ${STD_HELP_FILES_12} \
|
||||
${BLT_HELP_FILES_13} ${STD_HELP_FILES_14} \
|
||||
${BLT_HELP_FILES_14} ${STD_HELP_FILES_15}
|
||||
${STD_HELP_FILES_15} ${BLT_HELP_FILES_16} \
|
||||
${STD_HELP_FILES_17}
|
||||
|
||||
# These full files are those who are not built or constructed
|
||||
#
|
||||
STD_HELP_FILES= ${STD_HELP_FILES_1} ${STD_HELP_FILES_2} \
|
||||
${STD_HELP_FILES_4} ${STD_HELP_FILES_6} \
|
||||
${STD_HELP_FILES_8} ${STD_HELP_FILES_10} \
|
||||
${STD_HELP_FILES_10b} \
|
||||
${STD_HELP_FILES_12} ${STD_HELP_FILES_14} \
|
||||
${STD_HELP_FILES_15}
|
||||
${STD_HELP_FILES_15} ${STD_HELP_FILES_17}
|
||||
|
||||
# These full files are those who are built by this Makefile
|
||||
#
|
||||
# Note that ${SPECIAL_HELP_7} is not included in this list
|
||||
# because of problems with its name.
|
||||
#
|
||||
BLT_HELP_FILES= ${BLT_HELP_FILES_3} ${BLT_HELP_FILES_5} \
|
||||
${BLT_HELP_FILES_9} \
|
||||
${BLT_HELP_FILES_10a} \
|
||||
${BLT_HELP_FILES_11} ${BLT_HELP_FILES_13} \
|
||||
${BLT_HELP_FILES_14}
|
||||
BLT_HELP_FILES= ${BLT_HELP_FILES_1a} \
|
||||
${BLT_HELP_FILES_3} ${BLT_HELP_FILES_5} \
|
||||
${BLT_HELP_FILES_9} ${BLT_HELP_FILES_11} \
|
||||
${BLT_HELP_FILES_13} ${BLT_HELP_FILES_16}
|
||||
|
||||
# The detailed list of help files to install
|
||||
#
|
||||
@@ -254,10 +243,18 @@ DISTLIST= ${STD_HELP_FILES} ${DETAIL_HELP} ${MAKE_FILE} \
|
||||
# These files are used to make (but not built) a calc .a link library
|
||||
#
|
||||
CALCLIBLIST=
|
||||
|
||||
# complete list of files that may be created as part of the build process
|
||||
#
|
||||
# Used by chk_tree via make prep
|
||||
#
|
||||
BUILD_ALL= ${BLT_HELP_FILES} ${SINGULAR_FILES} ${DETAIL_CLONE} \
|
||||
full funclist${EXT} funclist.c funclist.o
|
||||
|
||||
# rules that are not also names of files
|
||||
#
|
||||
PHONY= all clobber distlist install
|
||||
PHONY= all distlist buildlist distdir calcliblist detail_help_list \
|
||||
echo_inst_files clean clobber install uninstall
|
||||
|
||||
|
||||
############################################################
|
||||
@@ -278,6 +275,8 @@ all: ${FULL_HELP_FILES} full ${DETAIL_HELP} ${DETAIL_CLONE} \
|
||||
# additional Makefile targets #
|
||||
###############################
|
||||
|
||||
.PHONY: ${PHONY}
|
||||
|
||||
# used by the upper level Makefile to determine of we have done all
|
||||
#
|
||||
# NOTE: Due to bogus shells found on one common system we must have
|
||||
@@ -287,8 +286,6 @@ all: ${FULL_HELP_FILES} full ${DETAIL_HELP} ${DETAIL_CLONE} \
|
||||
${RM} -f .all
|
||||
${TOUCH} .all
|
||||
|
||||
.PHONY: ${PHONY}
|
||||
|
||||
bindings: ../cal/bindings
|
||||
${RM} -f $@
|
||||
${CP} ../cal/bindings $@
|
||||
@@ -374,7 +371,7 @@ errorcodes: ../errcode${EXT}
|
||||
${TRUE}; \
|
||||
fi
|
||||
|
||||
usage: ../calc.usage
|
||||
calc: ../calc.usage
|
||||
${RM} -f $@
|
||||
${CP} ../calc.usage $@
|
||||
${CHMOD} 0444 $@
|
||||
@@ -425,18 +422,6 @@ copy: blkcpy
|
||||
${TRUE}; \
|
||||
fi
|
||||
|
||||
man: help
|
||||
${RM} -f $@
|
||||
${CP} help $@
|
||||
${CHMOD} 0444 $@
|
||||
-@if [ -z "${Q}" ]; then \
|
||||
echo ''; \
|
||||
echo '=-=-= skipping the ${CAT} of help/$@ =-=-='; \
|
||||
echo ''; \
|
||||
else \
|
||||
${TRUE}; \
|
||||
fi
|
||||
|
||||
COPYING: ../COPYING
|
||||
${RM} -f $@
|
||||
${CP} ../COPYING $@
|
||||
@@ -619,6 +604,13 @@ distlist: ${DISTLIST}
|
||||
fi; \
|
||||
done | fgrep -v '.bak' | LANG=C ${SORT}
|
||||
|
||||
buildlist:
|
||||
${Q} for i in ${BUILD_ALL} /dev/null; do \
|
||||
if [ X"$$i" != X"/dev/null" ]; then \
|
||||
echo help/$$i; \
|
||||
fi; \
|
||||
done | fgrep -v '.bak' | LANG=C ${SORT}
|
||||
|
||||
distdir:
|
||||
${Q} echo help
|
||||
|
||||
@@ -683,7 +675,7 @@ clean:
|
||||
${RM} -f COPYING COPYING-LGPL questions
|
||||
|
||||
clobber: clean
|
||||
${RM} -f ${BLT_HELP_FILES} full .all calc
|
||||
${RM} -f ${BLT_HELP_FILES} full .all calc man usage
|
||||
${RM} -f ${SINGULAR_FILES} ${DETAIL_CLONE}
|
||||
-${Q} if [ -e .DS_Store ]; then \
|
||||
echo ${RM} -rf .DS_Store; \
|
||||
@@ -751,6 +743,14 @@ install: all
|
||||
${RM} -f ${T}${HELPDIR}/md5; \
|
||||
echo "removed old ${T}${HELPDIR}/md5"; \
|
||||
fi;
|
||||
-${Q} if [ -f "${T}${HELPDIR}/man" ]; then \
|
||||
${RM} -f ${T}${HELPDIR}/man; \
|
||||
echo "removed old ${T}${HELPDIR}/man"; \
|
||||
fi;
|
||||
-${Q} if [ -f "${T}${HELPDIR}/usage" ]; then \
|
||||
${RM} -f ${T}${HELPDIR}/usage; \
|
||||
echo "removed old ${T}${HELPDIR}/usage"; \
|
||||
fi;
|
||||
|
||||
# Try to remove everything that was installed
|
||||
#
|
||||
|
75
help/address
75
help/address
@@ -113,7 +113,7 @@ DESCRIPTION
|
||||
|
||||
(the case of f(0) is exceptional since 27 + 0 simply copies the 27
|
||||
rather than creating a new number value). Here it is clearly more
|
||||
efficient to use
|
||||
efficient to use:
|
||||
|
||||
; A = B = C = f(2);
|
||||
|
||||
@@ -125,11 +125,74 @@ DESCRIPTION
|
||||
and number-pointer respectively, and 0 otherwise.
|
||||
|
||||
The output when addresses are printed consists of a description (o_ptr,
|
||||
v_ptr, s_ptr, n_ptr) followed by : and the address printed in
|
||||
%p format.
|
||||
v_ptr, s_ptr, n_ptr) followed by : and the address printed in %p format.
|
||||
|
||||
Iteration of & is not permitted; &&X causes a "non-variable operand"
|
||||
scan error.
|
||||
Iteration of & is not permitted; &(&X) causes a "Addressing
|
||||
non-addressable type" scan error.
|
||||
|
||||
RESTRICTIONS ON VALUE ADDRESS ARITHMETIC
|
||||
Most arithmetic operations on addresses of values are not permitted.
|
||||
For example one may not perform arithmetic operations (like +, ++,
|
||||
-, --, *, /, etc.) on an address of a value with a numeric value.
|
||||
|
||||
The reason why most arithmetic operations were removed from calc
|
||||
because arithmetic on addresses of calc objects could easily cause
|
||||
calc to crash. Consider this horrific expression that was allowed
|
||||
in calc prior to version 2.16.0.0:
|
||||
|
||||
; *((&.)+1e9) /* INVALID: for calc version >= 2.16.0.0 */
|
||||
|
||||
Prior to calc version 2.16.0.0, some arithmetic operations on
|
||||
addresses of values were permitted. Starting with calc version
|
||||
2.16.0.0, arithmetic operations between an addresses and an integer
|
||||
will return an error code:
|
||||
|
||||
; ++p; /* INVALID: will be set to E_INVALID_ADDR_OP */
|
||||
; r = q - 2; /* INVALID: will be set to E_INVALID_ADDR_OP */
|
||||
|
||||
Adding two value addresses is NOT permitted:
|
||||
|
||||
; mat A[3];
|
||||
; p = &A[1];
|
||||
; q = &A[2];
|
||||
; s = p + q; /* INVALID: will be set to E_INVALID_ADDR_OP */
|
||||
|
||||
Subtracting two value addresses is permitted, however there is NO
|
||||
guarantee that the address of a value will remain consistent across
|
||||
calc runs. Addresses of values depend on the circumstances of when
|
||||
the calc values were formed. For example:
|
||||
|
||||
; a = 3; pa = &a;
|
||||
; /* ... stuff happens ... */
|
||||
; b = 5; pb = &b;
|
||||
; t = pa - pb; /* permitted: value depends on circumstances */
|
||||
|
||||
Subtracting value addresses of components with the same compound
|
||||
object, such as a matrix, is permitted. For example:
|
||||
|
||||
; mat M[10] = {0,1,2,3,4,5,6,7,8,9};
|
||||
; i = 4; j = 5;
|
||||
; p = &M[i]; q = &M[j];
|
||||
; v = p - q; /* permitted: value depends on circumstances */
|
||||
|
||||
Comparison between two value addresses is permitted, however the
|
||||
same caveats apply as to the subtracting of addresses:
|
||||
|
||||
; if (p < q) {
|
||||
;; print "permitted: p is less than q";
|
||||
;; } else if (p == q) {
|
||||
;; print "permitted: p is equal to q";
|
||||
;; } else {
|
||||
;; print "permitted: p is greater than q";
|
||||
;; }
|
||||
|
||||
PLEASE NOTE:
|
||||
|
||||
The above restrictions and caveats apply to addresses of values.
|
||||
Such restrictions and caveats to NOT apply to the addresses of
|
||||
octets, NOR to the addresses within strings. If isptr(x) == 2,
|
||||
then x is value-pointer and the above mentioned restrictions
|
||||
and caveats apply it.
|
||||
|
||||
EXAMPLE
|
||||
Addresses for particular systems may differ from those displayed here.
|
||||
@@ -160,7 +223,7 @@ LINK LIBRARY
|
||||
SEE ALSO
|
||||
dereference, isptr
|
||||
|
||||
## Copyright (C) 1999-2006,2021 Landon Curt Noll
|
||||
## Copyright (C) 1999-2006,2021,2025 Landon Curt Noll
|
||||
##
|
||||
## Calc is open software; you can redistribute it and/or modify it under
|
||||
## the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
|
@@ -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,
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
10
help/help
10
help/help
@@ -5,7 +5,7 @@ following topics:
|
||||
----- -----------
|
||||
intro introduction to calc
|
||||
overview overview of calc
|
||||
help this file
|
||||
calc calc man page, how to invoke the calc command
|
||||
|
||||
assoc using associations
|
||||
builtin builtin functions
|
||||
@@ -13,7 +13,7 @@ following topics:
|
||||
config configuration parameters
|
||||
custom information about the custom builtin interface
|
||||
define how to define functions
|
||||
environment how environment variables effect calc
|
||||
environment how environment variables affect calc
|
||||
errorcodes calc generated error codes
|
||||
expression expression sequences
|
||||
file using files
|
||||
@@ -23,18 +23,17 @@ following topics:
|
||||
mat using matrices
|
||||
obj user defined data types
|
||||
operator math, relational, logic and variable access operators
|
||||
resource standard calc resource files
|
||||
script using calc shell scripts
|
||||
statement flow control and declaration statements
|
||||
types builtin data types
|
||||
unexpected unexpected syntax/usage surprises for C programmers
|
||||
usage how to invoke the calc command
|
||||
variable variables and variable declarations
|
||||
|
||||
bindings input & history character bindings
|
||||
custom_cal information about custom calc resource files
|
||||
libcalc using the arbitrary precision routines in a C program
|
||||
new_custom information about how to add new custom functions
|
||||
resource standard calc resource files
|
||||
script using calc shell scripts
|
||||
cscript info on the calc shell scripts supplied with calc
|
||||
|
||||
archive where to get the latest versions of calc
|
||||
@@ -51,6 +50,7 @@ following topics:
|
||||
questions how to ask simple general question about calc
|
||||
release on calc versions and releases
|
||||
|
||||
help this file
|
||||
full all of the above (in the above order)
|
||||
|
||||
For example:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
NAME
|
||||
log2 - base 10 logarithm
|
||||
log2 - base 2 logarithm
|
||||
|
||||
SYNOPSIS
|
||||
log2(x [,eps])
|
||||
|
@@ -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
|
||||
|
@@ -2,7 +2,7 @@ NAME
|
||||
mattrans - matrix transpose
|
||||
|
||||
SYNOPSIS
|
||||
matdim(m)
|
||||
mattrans(m)
|
||||
|
||||
TYPES
|
||||
m 2-dimensional matrix
|
||||
|
37
help/prompt
37
help/prompt
@@ -15,6 +15,39 @@ DESCRIPTION
|
||||
read from the input; the string formed by the characters in the line
|
||||
(other than the newline) is returned as the value of prompt().
|
||||
|
||||
Be careful when using prompt(str) while calc is being used as a
|
||||
shell script. Unless calc is run with the -p command line option,
|
||||
the prompt builtin will fail and return null. This is because when
|
||||
calc is running as a shell script, calc will close stdin run in in
|
||||
a non-interactive mode.
|
||||
|
||||
The following shell script will always print "got null" because
|
||||
stdin will be closed by calc during startup:
|
||||
|
||||
#!/usr/bin/calc -q -f
|
||||
|
||||
# The prompt will ALWAYS FAIL and return a null value
|
||||
n = prompt("Test> ");
|
||||
if (isnull(n)) {
|
||||
print("got null");
|
||||
} else {
|
||||
print("got " + n);
|
||||
}
|
||||
|
||||
However the following shell script (note the -p before the -f in
|
||||
the 1st line) will be interactive, prompt with "Test> " and print
|
||||
the "got" result as expected:
|
||||
|
||||
#!/usr/bin/calc -q -p -f
|
||||
|
||||
n = prompt("Test> ");
|
||||
if (isnull(n)) {
|
||||
print("got null");
|
||||
} else {
|
||||
print("got " + n);
|
||||
}
|
||||
|
||||
|
||||
EXAMPLE
|
||||
; x = prompt("? ");
|
||||
? 273
|
||||
@@ -35,9 +68,9 @@ LINK LIBRARY
|
||||
none
|
||||
|
||||
SEE ALSO
|
||||
fgetfield, fgetline, fgetstr
|
||||
command, fgetfield, fgetline, fgetstr, unexpected
|
||||
|
||||
## Copyright (C) 1999-2006 Landon Curt Noll
|
||||
## Copyright (C) 1999,2006,2023 Landon Curt Noll
|
||||
##
|
||||
## Calc is open software; you can redistribute it and/or modify it under
|
||||
## the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
|
@@ -1,5 +1,5 @@
|
||||
NAME
|
||||
randbit - Blum-Blum-Shub pseudo-random number generator
|
||||
randombit - Blum-Blum-Shub pseudo-random number generator
|
||||
|
||||
SYNOPSIS
|
||||
randombit([x])
|
||||
|
@@ -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.
|
||||
|
||||
@@ -556,6 +563,7 @@ Unexpected
|
||||
; print sin(d2r(30))
|
||||
0.5
|
||||
|
||||
|
||||
* operator has has a higher precedence than <<
|
||||
==============================================
|
||||
|
||||
@@ -563,6 +571,49 @@ Unexpected
|
||||
So 3 << 2*5 evaluates to 3072 in C, whereas 3 << 2*5 evaluates to 60 in calc.
|
||||
|
||||
|
||||
prompt builtin returns null in calc shell scripts unless -p is used
|
||||
===================================================================
|
||||
|
||||
Be careful when using prompt(str) while calc is being used as a
|
||||
shell script. Unless calc is run with the -p command line option,
|
||||
the prompt builtin will fail and return null. This is because when
|
||||
calc is running as a shell script, calc will close stdin run in in
|
||||
a non-interactive mode.
|
||||
|
||||
The following shell script will always print "got null" because
|
||||
stdin will be closed by calc during startup:
|
||||
|
||||
#!/usr/bin/calc -q -f
|
||||
|
||||
n = prompt("Test> ");
|
||||
if (isnull(n)) {
|
||||
print("got null");
|
||||
} else {
|
||||
print("got " + n);
|
||||
}
|
||||
|
||||
However the following shell script (note the -p before the -f in
|
||||
the 1st line) will be interactive, prompt with "Test> " and print
|
||||
the "got" result as expected:
|
||||
|
||||
#!/usr/bin/calc -q -p -f
|
||||
|
||||
n = prompt("Test> ");
|
||||
if (isnull(n)) {
|
||||
print("got null");
|
||||
} else {
|
||||
print("got " + n);
|
||||
}
|
||||
|
||||
Note in the example above, the -p flag must be given before the
|
||||
final -f command line flag.
|
||||
|
||||
A similar problem will occur if the calc shell script attempts
|
||||
to read from standard input (stdin), unless the -p flag is used.
|
||||
|
||||
See "SHELL SCRIPT MODE" in the calc man page for more information
|
||||
about -p and about the "shell script mode".
|
||||
|
||||
## Copyright (C) 1999-2007,2014,2017,2021,2023 Landon Curt Noll
|
||||
##
|
||||
## Calc is open software; you can redistribute it and/or modify it under
|
||||
|
56
hist.c
56
hist.c
@@ -73,6 +73,8 @@
|
||||
#include "banned.h" /* include after system header <> includes */
|
||||
|
||||
|
||||
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
|
||||
|
||||
#if !defined(USE_READLINE)
|
||||
|
||||
E_FUNC FILE *curstream(void);
|
||||
@@ -1474,18 +1476,24 @@ quit_calc(int UNUSED(ch))
|
||||
* For hist_getline() we have to add a newline that readline removed but
|
||||
* calc expects. For hist_saveline(), we have to undo this. hist_getline()
|
||||
* also has to cope with the different memory management schemes of calc and
|
||||
* readline.
|
||||
* readline (pointer to target buffer passed to hist_getline() vs. returned
|
||||
* malloc()ed buffer from readline()). While doing that, we also split
|
||||
* multi-line strings potentially returned by readline() in case of
|
||||
* bracketed paste mode even though its documentation promises to only return
|
||||
* single lines. For details, see https://github.com/lcn2/calc/issues/138
|
||||
* and https://lists.gnu.org/archive/html/bug-readline/2024-01/msg00000.html
|
||||
*/
|
||||
|
||||
|
||||
size_t
|
||||
hist_getline(char *prompt, char *buf, size_t len)
|
||||
{
|
||||
char *line;
|
||||
STATIC char *rlbuf, *rlcur;
|
||||
|
||||
if (!rlbuf) {
|
||||
rlbuf = rlcur = readline(prompt);
|
||||
if (!rlbuf) {
|
||||
buf[0] = '\0';
|
||||
line = readline(prompt);
|
||||
if (!line) {
|
||||
switch (conf->ctrl_d) {
|
||||
case CTRL_D_NEVER_EOF:
|
||||
return 0;
|
||||
@@ -1496,13 +1504,39 @@ hist_getline(char *prompt, char *buf, size_t len)
|
||||
not_reached();
|
||||
}
|
||||
}
|
||||
strlcpy(buf, line, len);
|
||||
buf[len - 2] = '\0';
|
||||
len = strlen(buf);
|
||||
buf[len] = '\n';
|
||||
buf[len + 1] = '\0';
|
||||
free(line);
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
/* eol: pointer to trailing newline (if there is one) or \0 */
|
||||
char *eol = strchr(rlcur, '\n');
|
||||
if (!eol) {
|
||||
eol = rlcur + strlen(rlcur);
|
||||
}
|
||||
/* len: length of line in target buffer including (possibly added)
|
||||
* newline, truncated if buffer is too small. Note that we reduce
|
||||
* the available buffer size by 1 so that we can safely add the
|
||||
* newline below.
|
||||
*/
|
||||
len = MIN(len - 1, (size_t)(eol - rlcur + 1));
|
||||
strlcpy(buf, rlcur, len);
|
||||
/* make sure we have a newline and NUL */
|
||||
buf[len - 1] = '\n';
|
||||
buf[len] = '\0';
|
||||
|
||||
/* skip over newline in readline buffer */
|
||||
if (*eol) {
|
||||
eol++;
|
||||
}
|
||||
/* prepare for next invocation: point to next line or free readline
|
||||
* buffer if we've reached EOL
|
||||
*/
|
||||
if (*eol) {
|
||||
rlcur = eol;
|
||||
} else {
|
||||
free(rlbuf);
|
||||
rlbuf = rlcur = NULL;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -959,8 +959,8 @@ o_deref(FUNC *UNUSED(fp))
|
||||
return;
|
||||
}
|
||||
if (stack->v_type != V_ADDR) {
|
||||
math_error("Dereferencing a non-variable");
|
||||
not_reached();
|
||||
*stack = error_value(E_INVALID_DEREF);
|
||||
return;
|
||||
}
|
||||
vp = vp->v_addr;
|
||||
switch (vp->v_type) {
|
||||
|
2
qfunc.c
2
qfunc.c
@@ -1953,7 +1953,7 @@ qispowerof2(NUMBER *q, NUMBER **qlog2)
|
||||
* Set *qlog2 to base 2 logarithm of q, which will be a negative value,
|
||||
* and return true.
|
||||
*/
|
||||
*qlog2 = utoq(log2);
|
||||
**qlog2 = *utoq(log2);
|
||||
(*qlog2)->num.sign = !(*qlog2)->num.sign; /* set *qlog2 to -log2 */
|
||||
return true;
|
||||
}
|
||||
|
98
str.c
98
str.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* str - string list routines
|
||||
*
|
||||
* Copyright (C) 1999-2007,2021-2023 David I. Bell and Ernest Bowen
|
||||
* Copyright (C) 1999-2007,2021-2023,2025 David I. Bell and Ernest Bowen
|
||||
*
|
||||
* Primary author: David I. Bell
|
||||
*
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "banned.h" /* include after system header <> includes */
|
||||
|
||||
|
||||
#define STR_TABLECHUNK (1<<10) /* how often to reallocate string table */
|
||||
#define STR_TABLECHUNK (1<<16) /* how often to reallocate string literal table */
|
||||
#define STR_CHUNK (1<<16) /* size of string storage allocation */
|
||||
#define OCTET_VALUES 256 /* number of different values in a OCTET */
|
||||
#define STR_UNIQUE (1<<7) /* size of string to allocate separately */
|
||||
@@ -97,6 +97,10 @@ initstr(STRINGHEAD *hp)
|
||||
* given:
|
||||
* hp header of string storage
|
||||
* str string to be added
|
||||
*
|
||||
* returns:
|
||||
* != NULL ==> pointer to newly added string
|
||||
* NULL ==> unable to add string
|
||||
*/
|
||||
char *
|
||||
addstr(STRINGHEAD *hp, char *str)
|
||||
@@ -113,6 +117,10 @@ addstr(STRINGHEAD *hp, char *str)
|
||||
/* alloc + 1 guard paranoia */
|
||||
newsize = len + STR_CHUNK + hp->h_used + hp->h_avail + 1;
|
||||
/* alloc + 1 guard paranoia */
|
||||
/*
|
||||
* XXX - doing a realloc can cause problems if the larger list has to be
|
||||
* relocated due the recalloc() call and stuff point to old location
|
||||
*/
|
||||
list = (char *)realloc(hp->h_list, newsize + 1);
|
||||
if (list == NULL)
|
||||
return NULL;
|
||||
@@ -130,35 +138,6 @@ addstr(STRINGHEAD *hp, char *str)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a null-terminated string which consists of a single character.
|
||||
* The table is initialized on the first call.
|
||||
*/
|
||||
char *
|
||||
charstr(int ch)
|
||||
{
|
||||
char *cp;
|
||||
int i;
|
||||
|
||||
if (chartable == NULL) {
|
||||
/* alloc + 1 guard paranoia */
|
||||
cp = (char *)malloc((OCTET_VALUES + 1)*2);
|
||||
if (cp == NULL) {
|
||||
math_error("Cannot allocate character table");
|
||||
not_reached();
|
||||
}
|
||||
for (i = 0; i < OCTET_VALUES; i++) {
|
||||
*cp++ = (char)i;
|
||||
*cp++ = '\0';
|
||||
}
|
||||
chartable = cp - (OCTET_VALUES*2);
|
||||
*cp++ = '\0'; /* guard paranoia */
|
||||
*cp++ = '\0'; /* guard paranoia */
|
||||
}
|
||||
return &chartable[(ch & 0xff) * 2];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find a string with the specified name and return its number in the
|
||||
* string list. The first string is numbered zero. Minus one is returned
|
||||
@@ -166,7 +145,11 @@ charstr(int ch)
|
||||
*
|
||||
* given:
|
||||
* hp header of string storage
|
||||
* str string to be added
|
||||
* str string to be searched for
|
||||
*
|
||||
* returns:
|
||||
* >= 0 ==> index of string
|
||||
* -1 ==> unable to find string
|
||||
*/
|
||||
int
|
||||
findstr(STRINGHEAD *hp, char *str)
|
||||
@@ -200,6 +183,10 @@ findstr(STRINGHEAD *hp, char *str)
|
||||
* given:
|
||||
* hp header of string storage
|
||||
* n string index
|
||||
*
|
||||
* returns:
|
||||
* non-empty string ==> string at index n
|
||||
* "" ==> no strings or string at index n
|
||||
*/
|
||||
char *
|
||||
namestr(STRINGHEAD *hp, long n)
|
||||
@@ -219,36 +206,31 @@ namestr(STRINGHEAD *hp, long n)
|
||||
|
||||
|
||||
/*
|
||||
* Useful routine to return the index of one string within another one
|
||||
* which has the format: "str1\000str2\000str3\000...strn\0\0". Index starts
|
||||
* at one for the first string. Returns zero if the string being checked
|
||||
* is not contained in the formatted string.
|
||||
*
|
||||
* Be sure to use \000 instead of \0. ANSI-C compilers interpret "foo\0foo..."
|
||||
* as "foo\017oo...".
|
||||
*
|
||||
* given:
|
||||
* format string formatted into substrings
|
||||
* test string to be found in formatted string
|
||||
* Return a null-terminated string which consists of a single character.
|
||||
* The table is initialized on the first call.
|
||||
*/
|
||||
long
|
||||
stringindex(char *format, char *test)
|
||||
S_FUNC char *
|
||||
charstr(int ch)
|
||||
{
|
||||
long index; /* found index */
|
||||
size_t len; /* length of current piece of string */
|
||||
size_t testlen; /* length of test string */
|
||||
char *cp;
|
||||
int i;
|
||||
|
||||
testlen = strlen(test);
|
||||
index = 1;
|
||||
while (*format) {
|
||||
len = strlen(format);
|
||||
if ((len == testlen) && (*format == *test) &&
|
||||
(strcmp(format, test) == 0))
|
||||
return index;
|
||||
format += (len + 1);
|
||||
index++;
|
||||
if (chartable == NULL) {
|
||||
/* alloc + 1 guard paranoia */
|
||||
cp = (char *)malloc((OCTET_VALUES + 1)*2);
|
||||
if (cp == NULL) {
|
||||
math_error("Cannot allocate character table");
|
||||
not_reached();
|
||||
}
|
||||
return 0;
|
||||
for (i = 0; i < OCTET_VALUES; i++) {
|
||||
*cp++ = (char)i;
|
||||
*cp++ = '\0';
|
||||
}
|
||||
chartable = cp - (OCTET_VALUES*2);
|
||||
*cp++ = '\0'; /* guard paranoia */
|
||||
*cp++ = '\0'; /* guard paranoia */
|
||||
}
|
||||
return &chartable[(ch & 0xff) * 2];
|
||||
}
|
||||
|
||||
|
||||
|
4
str.h
4
str.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* str - string list routines
|
||||
*
|
||||
* Copyright (C) 1999-2007,2014 David I. Bell
|
||||
* Copyright (C) 1999-2007,2014,2025 David I. Bell
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -59,9 +59,7 @@ E_FUNC void initstr(STRINGHEAD *hp);
|
||||
E_FUNC char *addstr(STRINGHEAD *hp, char *str);
|
||||
E_FUNC char *namestr(STRINGHEAD *hp, long n);
|
||||
E_FUNC int findstr(STRINGHEAD *hp, char *str);
|
||||
E_FUNC char *charstr(int ch);
|
||||
E_FUNC char *addliteral(char *str);
|
||||
E_FUNC long stringindex(char *str1, char *str2);
|
||||
E_FUNC STRING *stralloc(void);
|
||||
E_FUNC long addstring(char *str, size_t len);
|
||||
E_FUNC STRING *charstring(int ch);
|
||||
|
67
trailblank
67
trailblank
@@ -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 debug.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 debug.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.
|
||||
#
|
||||
@@ -154,8 +181,9 @@ PICKY_PHASE_1=$(
|
||||
-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 debug.out -o \
|
||||
-name '.gitignore' -o -name 'README.md' -o -name '.lldbinit' \
|
||||
-name 'codeql-analysis.yml' -o -name tags -o -name '*.out' -o \
|
||||
-iname '*foo*' -o -iname '*bar*' -o -iname '*baz*' -o \
|
||||
-name '.lldbinit' -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,12 +212,41 @@ 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
|
||||
fi
|
||||
|
||||
|
||||
# look for ASCII tabs in non-Makefiles
|
||||
#
|
||||
TABS_FOUND=$(
|
||||
find . \( -path './NOTES' -o -path './calc' -o -path './ver_calc' -o \
|
||||
-name '*.o' -o -name '*.a' -o -name '*ptch*' -o -name 'core*' -o \
|
||||
-name '*.orig' -o -name '*.rej' -o -name '*.bak' -o \
|
||||
-name '*.ptch' -o -name 'core.*' -o \
|
||||
-name '*.so*' -o -name 'calc-static' -o -name 'libcalc.*' -o \
|
||||
-name 'sample_many' -o -name 'sample_rand' -o -name 'errcode' -o \
|
||||
-path './help/funclist' -o -path './have_stdvs' -o \
|
||||
-path './endian' -o -path './no_implicit' -o -name 'chk_c' -o \
|
||||
-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' -o \
|
||||
-iname '*foo*' -o -iname '*bar*' -o -iname '*baz*' -o \
|
||||
-name '.lldbinit' -o -iname '*curds*' -o -iname '*whey*' -o -iname '*rmme*' -o \
|
||||
-iname 'Makefile*' -o -name rpm.mk -o -name 'trailblank' \
|
||||
\) -prune -o -type f -print0 | \
|
||||
xargs -0 grep -l -E ' '
|
||||
)
|
||||
if [[ -n $TABS_FOUND ]]; then
|
||||
echo
|
||||
echo '# ASCII TABs found in non-Makefiles:'
|
||||
echo "$TABS_FOUND"
|
||||
EXIT_CODE=8
|
||||
fi
|
||||
|
||||
# All Done!!! -- Jessica Noll, Age 2
|
||||
#
|
||||
exit "$EXIT_CODE"
|
||||
|
30
update_ver
30
update_ver
@@ -169,6 +169,7 @@ for i in $MK_SET1; do
|
||||
echo "$i: $VER_STRING"
|
||||
fi
|
||||
done
|
||||
echo
|
||||
if [[ -n $VER_ERR ]]; then
|
||||
echo "$0: FATAL: error in finding calc major version string"
|
||||
echo "$0: FATAL: exit 10"
|
||||
@@ -177,13 +178,36 @@ fi
|
||||
|
||||
# print other useful calc strings
|
||||
#
|
||||
export VER_CALC_OUTPUT=$(./ver_calc)
|
||||
echo 'Begin text strings used to produce this release:'
|
||||
echo 'vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv'
|
||||
echo
|
||||
echo "calc $(./ver_calc) release"
|
||||
echo
|
||||
echo "Release v$(./ver_calc)"
|
||||
echo
|
||||
echo "$VER_CALC_OUTPUT"
|
||||
echo
|
||||
echo "v$VER_CALC_OUTPUT"
|
||||
echo
|
||||
echo "Release v$VER_CALC_OUTPUT"
|
||||
echo
|
||||
echo "calc $VER_CALC_OUTPUT release"
|
||||
echo
|
||||
echo 'For use with sourceforge.net:'
|
||||
echo
|
||||
echo 'cd /home/pfs/project/calc/calc'
|
||||
echo "mkdir $VER_CALC_OUTPUT"
|
||||
echo "cd $VER_CALC_OUTPUT"
|
||||
echo 'mput calc-*'"$VER_CALC_OUTPUT"'*'
|
||||
echo 'put /home/chongo/tmp/README.txt'
|
||||
echo 'ls'
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'
|
||||
echo 'End text strings used to produce this release:'
|
||||
echo
|
||||
|
||||
# All Done!!! -- Jessica Noll, Age 2
|
||||
#
|
||||
echo
|
||||
echo "VERSION in Makefile.config is up to date"
|
||||
exit 0
|
||||
|
23
value.c
23
value.c
@@ -434,6 +434,8 @@ addvalue(VALUE *v1, VALUE *v2, VALUE *vres)
|
||||
*vres = error_value(E_STRADD);
|
||||
return;
|
||||
case TWOVAL(V_VPTR, V_NUM):
|
||||
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||
/* NOTE: Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported! */
|
||||
q = v2->v_num;
|
||||
if (qisfrac(q)) {
|
||||
math_error("Adding non-integer to address");
|
||||
@@ -442,6 +444,12 @@ addvalue(VALUE *v1, VALUE *v2, VALUE *vres)
|
||||
i = qtoi(q);
|
||||
vres->v_addr = v1->v_addr + i;
|
||||
vres->v_type = V_VPTR;
|
||||
#else /* Disable arithmetic on addresses */
|
||||
*vres = error_value(E_INVALID_ADDR_OP);
|
||||
#endif /* Disable arithmetic on addresses */
|
||||
return;
|
||||
case TWOVAL(V_VPTR, V_VPTR):
|
||||
*vres = error_value(E_INVALID_ADDR_OP);
|
||||
return;
|
||||
case TWOVAL(V_OPTR, V_NUM):
|
||||
q = v2->v_num;
|
||||
@@ -515,6 +523,8 @@ subvalue(VALUE *v1, VALUE *v2, VALUE *vres)
|
||||
*vres = error_value(E_STRSUB);
|
||||
return;
|
||||
case TWOVAL(V_VPTR, V_NUM):
|
||||
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||
/* NOTE: Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported! */
|
||||
q = v2->v_num;
|
||||
if (qisfrac(q)) {
|
||||
math_error("Subtracting non-integer from address");
|
||||
@@ -523,6 +533,9 @@ subvalue(VALUE *v1, VALUE *v2, VALUE *vres)
|
||||
i = qtoi(q);
|
||||
vres->v_addr = v1->v_addr - i;
|
||||
vres->v_type = V_VPTR;
|
||||
#else /* Disable arithmetic on addresses */
|
||||
*vres = error_value(E_INVALID_ADDR_OP);
|
||||
#endif /* Disable arithmetic on addresses */
|
||||
return;
|
||||
case TWOVAL(V_OPTR, V_NUM):
|
||||
q = v2->v_num;
|
||||
@@ -1407,7 +1420,12 @@ incvalue(VALUE *vp, VALUE *vres)
|
||||
vres->v_octet = vp->v_octet + 1;
|
||||
break;
|
||||
case V_VPTR:
|
||||
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||
/* NOTE: Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported! */
|
||||
vres->v_addr = vp->v_addr + 1;
|
||||
#else /* Disable arithmetic on addresses */
|
||||
*vres = error_value(E_INVALID_ADDR_OP);
|
||||
#endif /* Disable arithmetic on addresses */
|
||||
break;
|
||||
default:
|
||||
if (vp->v_type > 0)
|
||||
@@ -1443,7 +1461,12 @@ decvalue(VALUE *vp, VALUE *vres)
|
||||
vres->v_octet = vp->v_octet - 1;
|
||||
break;
|
||||
case V_VPTR:
|
||||
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||
/* NOTE: Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported! */
|
||||
vres->v_addr = vp->v_addr - 1;
|
||||
#else /* Disable arithmetic on addresses */
|
||||
*vres = error_value(E_INVALID_ADDR_OP);
|
||||
#endif /* Disable arithmetic on addresses */
|
||||
break;
|
||||
default:
|
||||
if (vp->v_type >= 0)
|
||||
|
@@ -80,7 +80,13 @@ char *Copyright = "\n"
|
||||
"\n"
|
||||
"Calc is open software; you can redistribute it and/or modify it under\n"
|
||||
"the terms of the version 2.1 of the GNU Lesser General Public License\n"
|
||||
"as published by the Free Software Foundation.\n";
|
||||
"as published by the Free Software Foundation.\n"
|
||||
"\n"
|
||||
"Please see the file COPYING, or use the calc command:\n"
|
||||
"\n"
|
||||
"\thelp copying\n"
|
||||
"\n"
|
||||
"for important copyright and license information!\n";
|
||||
char *Usability = "\n"
|
||||
"Calc is distributed in the hope that it will be useful, but WITHOUT\n"
|
||||
"ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n"
|
||||
|
17
version.h
17
version.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* version - determine the version of calc
|
||||
*
|
||||
* Copyright (C) 2023 David I. Bell and Landon Curt Noll
|
||||
* Copyright (C) 1989-2025 David I. Bell and Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -62,9 +62,22 @@
|
||||
* bug fix and improvement updates will cause MINOR_PATCH to increment.
|
||||
*/
|
||||
#define MAJOR_VER 2 /* level 1: major library version */
|
||||
#define MINOR_VER 15 /* level 2: minor library version */
|
||||
#define MINOR_VER 16 /* level 2: minor library version */
|
||||
#define MAJOR_PATCH 0 /* level 3: major software version level */
|
||||
#define MINOR_PATCH 0 /* level 4: minor software version level */
|
||||
|
||||
/*
|
||||
* Defining PERMIT_DANGEROUS_ADDRESS_ARITHMETIC is NOT supported!
|
||||
*
|
||||
* If someone were to be a foolish as to permit dangerous address arithmetic, then we
|
||||
* negate the major version to further "disavow" such a calc compile.
|
||||
*/
|
||||
#if defined(PERMIT_DANGEROUS_ADDRESS_ARITHMETIC)
|
||||
# undef TEMP_MAJOR_VER
|
||||
# define TEMP_MAJOR_VER MAJOR_VER
|
||||
# undef MAJOR_VER
|
||||
# define MAJOR_VER (-TEMP_MAJOR_VER)
|
||||
# undef TEMP_MAJOR_VER
|
||||
#endif
|
||||
|
||||
#endif /* !INCLUDE_VERSION_H*/
|
||||
|
18
zmath.h
18
zmath.h
@@ -79,7 +79,7 @@ typedef USB64 FULL; /* double unit of number storage */
|
||||
typedef SB64 SFULL; /* signed FULL */
|
||||
|
||||
#define SWAP_HALF_IN_B64(dest, src) SWAP_B32_IN_B64(dest, src)
|
||||
#define SWAP_HALF_IN_B32(dest, src) (*(dest) = *(src))
|
||||
#define SWAP_HALF_IN_B32(dest, src) (*((HALF *)(dest)) = *((HALF *)(src)))
|
||||
#define SWAP_HALF_IN_FULL(dest, src) SWAP_B32_IN_B64(dest, src)
|
||||
#define SWAP_HALF_IN_HASH(dest, src) SWAP_B16_IN_HASH(dest, src)
|
||||
#define SWAP_HALF_IN_FLAG(dest, src) SWAP_B16_IN_FLAG(dest, src)
|
||||
@@ -106,9 +106,9 @@ typedef SB32 SFULL; /* signed FULL */
|
||||
#define SWAP_HALF_IN_FLAG(dest, src) SWAP_B16_IN_FLAG(dest, src)
|
||||
#define SWAP_HALF_IN_bool(dest, src) SWAP_B16_IN_bool(dest, src)
|
||||
#define SWAP_HALF_IN_LEN(dest, src) SWAP_B16_IN_LEN(dest, src)
|
||||
#define SWAP_B32_IN_FULL(dest, src) (*(dest) = *(src))
|
||||
#define SWAP_B32_IN_FULL(dest, src) (*((FULL *)(dest)) = *((FULL *)(src)))
|
||||
#define SWAP_B16_IN_FULL(dest, src) SWAP_B16_IN_B32(dest, src)
|
||||
#define SWAP_B16_IN_HALF(dest, src) (*(dest) = *(src))
|
||||
#define SWAP_B16_IN_HALF(dest, src) (*((HALF *)(dest)) = *((HALF *)(src)))
|
||||
#define SWAP_B8_IN_FULL(dest, src) SWAP_B8_IN_B32(dest, src)
|
||||
#define SWAP_B8_IN_HALF(dest, src) SWAP_B8_IN_B16(dest, src)
|
||||
|
||||
@@ -171,19 +171,11 @@ typedef SB32 LEN; /* calc v2 compatible unit of length storage */
|
||||
typedef uintptr_t LEN; /* unit of length storage */
|
||||
#endif /* MAJOR_VER < 3 */
|
||||
|
||||
#define SWAP_B32_IN_HASH(dest, src) (*(dest) = *(src))
|
||||
#define SWAP_B16_IN_HASH(dest, src) SWAP_B16_IN_B32(dest, src)
|
||||
#define SWAP_B8_IN_HASH(dest, src) SWAP_B8_IN_B32(dest, src)
|
||||
|
||||
#define SWAP_B32_IN_FLAG(dest, src) (*(dest) = *(src))
|
||||
#define SWAP_B16_IN_FLAG(dest, src) SWAP_B16_IN_B32(dest, src)
|
||||
#define SWAP_B8_IN_FLAG(dest, src) SWAP_B8_IN_B32(dest, src)
|
||||
|
||||
#define SWAP_B32_IN_bool(dest, src) (*(dest) = *(src))
|
||||
#define SWAP_B32_IN_bool(dest, src) (*((bool *)(dest)) = *((bool *)(src)))
|
||||
#define SWAP_B16_IN_bool(dest, src) SWAP_B16_IN_B32(dest, src)
|
||||
#define SWAP_B8_IN_bool(dest, src) SWAP_B8_IN_B32(dest, src)
|
||||
|
||||
#define SWAP_B32_IN_LEN(dest, src) (*(dest) = *(src))
|
||||
#define SWAP_B32_IN_LEN(dest, src) (*((LEN *)(dest)) = *((LEN *)(src)))
|
||||
#define SWAP_B16_IN_LEN(dest, src) SWAP_B16_IN_B32(dest, src)
|
||||
#define SWAP_B8_IN_LEN(dest, src) SWAP_B8_IN_B32(dest, src)
|
||||
|
||||
|
66
zrandom.c
66
zrandom.c
@@ -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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
if (blum_initialized == true) {
|
||||
randomfree(&blum);
|
||||
}
|
||||
blum = *p_blum;
|
||||
free(p_blum);
|
||||
blum_initialized = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2657,6 +2679,9 @@ zsetrandom(CONST RANDOM *state)
|
||||
*/
|
||||
if (state != NULL) {
|
||||
p_blum = randomcopy(state);
|
||||
if (blum_initialized == true) {
|
||||
randomfree(&blum);
|
||||
}
|
||||
blum = *p_blum;
|
||||
free(p_blum);
|
||||
}
|
||||
@@ -2684,11 +2709,14 @@ zrandomskip(long cnt)
|
||||
/*
|
||||
* initialize state if first call
|
||||
*/
|
||||
if (!blum.seeded) {
|
||||
if (blum_initialized == false || !blum.seeded) {
|
||||
p_blum = randomcopy(&init_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 +2826,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);
|
||||
if (blum_initialized == true) {
|
||||
randomfree(&blum);
|
||||
}
|
||||
blum = *p_blum;
|
||||
free(p_blum);
|
||||
blum_initialized = true;
|
||||
}
|
||||
loglogn = blum.loglogn;
|
||||
mask = blum.mask;
|
||||
@@ -3120,16 +3151,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 +3256,10 @@ randomprint(CONST RANDOM *UNUSED(state), int UNUSED(flags))
|
||||
void
|
||||
random_libcalc_cleanup(void)
|
||||
{
|
||||
/* free our state - let zfree_random protect the default state */
|
||||
/* free our state if seed was initialized - zfree_random protect default states */
|
||||
if (blum_initialized == true && blum.seeded) {
|
||||
randomfree(&blum);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3238,6 +3273,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 &&
|
||||
|
Reference in New Issue
Block a user