Compare commits

..

39 Commits

Author SHA1 Message Date
Landon Curt Noll
37ad43c7fd Release calc 2.12.7.1
Corrected CHANGES notes that were mixed up for TAB, VT, CR &
NL.  The code in 2.12.7.0 is correct.  The CHANGE notes should
have read:

The following is a partial list of escape sequences recognized
in strings and in printf formats:

    \a	audible bell	byte 0x07 in ASCII encoding
    \b	backspace	byte 0x08 in ASCII encoding
    \f	form feed	byte 0x0c in ASCII encoding
    \n	newline		byte 0x0a in ASCII encoding
    \r	return		byte 0x0d in ASCII encoding
    \t	tab		byte 0x09 in ASCII encoding
    \v	vertical tab	byte 0x0b in ASCII encoding

Sorry!
2018-11-05 08:02:09 -08:00
Landon Curt Noll
a877cb52c0 Corrected CHANGES notes
Corrected CHANGES notes that were mixed up for TAB, VT, CR & NL.
The core in 2.12.7.0 is correct.  The CHANGE notes were mixed up.
Sorry!
2018-11-05 07:33:40 -08:00
Landon Curt Noll
4bec694df3 Release calc version 2.12.7.0
The following are the changes from calc version 2.12.7.0 to date:

    Added a patch to replaces the manual search for include files
    in $(INCDIR) in the have_*.h targets with compiler invocations.
    Thanks goes to Helmut Grohne (helmut at subdivi dot de) who
    implemented the patch and posted it to the Debian bug tracker
    and Martin Buck (m at rtin-buck dor de) for forwarding it to us.

    The check_include make rule was fixed to not assume /usr/include.

    The qprintnum() function now takes outdigits as a 3rd argument.
    Most of the time, this 3rd argument is just conf->outdigits.
    But when it comes to the experimental '%g', this value can
    change.  This avoids having to modify conf->outdigits.

    Fixed a problem where gcc complains about E_FUNC not being defined
    for Linux systems as reported by Martin Buck (m at rtin-buck dor de).

    Updated the help files help/config, help/display, help/epsilon,
    help/fprint, help/printf, and help/strprintf to give more
    examples of how display digits and epsilon precision interact
    with displaying values.

    Added more information about %g in the help file help/printf.

    The '\a' is now recognized in a printf format string as the
    single byte audible bell character (byte 0x07 in ASCII encoding).

    The following is a partial list of escape sequences recognized
    in strings and in printf formats:

        \a      audible bell    byte 0x07 in ASCII encoding
        \b      backspace       byte 0x08 in ASCII encoding
        \f      form feed       byte 0x0c in ASCII encoding
        \n      newline         byte 0x0b in ASCII encoding
        \r      return          byte 0x0a in ASCII encoding
        \t      tab             byte 0x0d in ASCII encoding
        \v      vertical tab    byte 0x09 in ASCII encoding
2018-11-04 17:11:31 -08:00
Landon Curt Noll
4870a7a164 Sync check_include rule with Makefile.ship 2018-11-04 17:10:46 -08:00
Landon Curt Noll
84ccb37bc3 Regualrize escape characters
Regularized the case statements in qio.c, str.c, and token.c
that relate to escape characters.

The '\a' is now recognized in a printf format string as the
single byte audible bell character (byte 0x07 in ASCII encoding).

The following is a partial list of escape sequences recognized
in strings and in printf formats:

    \a      audible bell    byte 0x07 in ASCII encoding
    \b      backspace       byte 0x08 in ASCII encoding
    \f      form feed       byte 0x0c in ASCII encoding
    \n      newline         byte 0x0b in ASCII encoding
    \r      return          byte 0x0a in ASCII encoding
    \t      tab             byte 0x0d in ASCII encoding
    \v      vertical tab    byte 0x09 in ASCII encoding
2018-11-04 17:08:11 -08:00
Landon Curt Noll
29c6e9325f Fix issue with E_FUNC under linux
Fixed a problem where gcc complains about E_FUNC not being defined
for Linux systems as reported by Martin Buck (m at rtin-buck dor de).
2018-11-04 17:01:24 -08:00
Landon Curt Noll
81a4a4f828 Improve string and printing documentation
Updated the help files help/config, help/display, help/epsilon,
help/fprint, help/printf, and help/strprintf to give more
examples of how display digits and epsilon precision interact
with displaying values.

Added more information about %g in the help file help/printf.

The '\a' is now recognized in a printf format string as the
single byte audible bell character (byte 0x07 in ASCII encoding).

The following is a partial list of escape sequences recognized
in strings and in printf formats:

    \a      audible bell    byte 0x07 in ASCII encoding
    \b      backspace       byte 0x08 in ASCII encoding
    \f      form feed       byte 0x0c in ASCII encoding
    \n      newline         byte 0x0b in ASCII encoding
    \r      return          byte 0x0a in ASCII encoding
    \t      tab             byte 0x0d in ASCII encoding
    \v      vertical tab    byte 0x09 in ASCII encoding
2018-11-04 17:00:15 -08:00
Landon Curt Noll
1cdb5172d8 Fix Makefile lines that picky complains about 2018-10-19 19:41:58 -07:00
Landon Curt Noll
54a7a3f7bc Release 2.12.6.10
Added a patch to replaces the manual search for include files
    in $(INCDIR) in the have_*.h targets with compiler invocations.
    Thanks goes to Helmut Grohne <helmut at subdivi dot de> who
    implemented the patch and posted it to the Debian bug tracker
    and Martin Buck (m at rtin-buck dor de) for forwarding it to us.

    The check_include make rule was fixed to not assume /usr/include.

    The qprintnum() function now takes outdigits as a 3rd argument.
    Most of the time, this 3rd argument is just conf->outdigits.
    But when it comes to the experimental '%g', this value can
    change.  This avoids having to modify conf->outdigits.
2018-10-19 19:33:57 -07:00
Landon Curt Noll
2ea77e6151 Release 2.12.6.9
Experimental changes for macOS builds.
2018-10-15 19:37:48 -07:00
Landon Curt Noll
5cfa6199e5 Merge branch '10110111-master' 2018-09-30 16:11:23 -07:00
Landon Curt Noll
da6ccc146f Improvements to %g pull request
This code %g is preliminary.

Fixed some code style issues to match the current code style.

Added regression tests and help file updates to printf and strprintf.

Fixed use of magic number -4: using -P instead.

Noted two problem areas with XXX comments in qio.c:

    1) need a qprintfg function
    2) re-write to not modify conf->outdigits
2018-09-30 16:06:28 -07:00
Landon Curt Noll
fcfe237375 Merge branch 'master' of https://github.com/10110111/calc into 10110111-master 2018-09-30 14:22:41 -07:00
Landon Curt Noll
5fb3db4558 Fixed trigonometric and hyperbolic core dumps 2018-09-30 14:08:20 -07:00
Landon Curt Noll
c8705c1198 Release calc 2.12.6.8
The following are the changes in this release:

    For historical purposes, in lucas.cal, gen_v1(1, n) always returns 4.

    Fixed some compiler warnings, thanks to a report by Mike
    <michael dot d dot ince at gmail dot com>.

    Added work around for a gcc warning bug, thanks to a report by Mike
    <michael dot d dot ince at gmail dot com>.

    Fixed errors in various help files such as:

	mat randbit seed srandom types

    Removed the MAXSTRING symbol because it was no longer used by calc.

    Increased HIST_SIZE (depth of the history stack) from 10k to 32k.

    Increased TTYSIZE (reallocation size for terminal buffers) from 100 to 8191.

    Increased MAXDEPTH (maximum depth of input stack) from 10 to 255.

    Increased interactive input buffer size from 1024 to 256k.  This has the
    effect of increasing the maximum length of an input line from a tty.
    This helps with an interactive bug that was reported by Ruslan Kabatsayev
    (b7 dot 10110111 at gmail dot com).

    The calc man page indicates that -d also disables the printing of the
    leading tilde.

    Added information to "help command" about how to silence messages
    while reading calc resource files.

    Fixed an error message buffer overflow thanks to a report by
    Frank Peters <nlp at northernlightsphoto dot biz>.

    Replaced all use of the C funcion sprintf() with snprintf().
    Replaced all use of the C funcion vsprintf() with vsnprintf().
    Replaced all DONT_HAVE_VSPRINTF with DONT_HAVE_VSNPRINTF.
    Replaced all Makefile var ${HAVE_VSPRINTF} with ${HAVE_VSNPRINTF}.
2018-09-30 10:25:18 -07:00
Ruslan Kabatsayev
0558bafcb6 Use MODE_REAL_AUTO by default instead of MODE_REAL
This will save the user from embarrassment due to getting
~0.00000000000000000000 as the result instead of e.g. 1.23e-53.
2018-06-30 18:44:14 +03:00
Ruslan Kabatsayev
f58277f53d Implement %g format for printf 2018-06-30 18:35:35 +03:00
Landon Curt Noll
e555a718c0 Released calc 2.12.6.7 with help and input fixes
Fixed errors in various help files such as:

	mat randbit seed srandom types

    Removed the MAXSTRING symbol because it was no longer used by calc.

    Increased HIST_SIZE (depth of the history stack) from 10k to 32k.

    Increased TTYSIZE (reallocation size for terminal buffers) from 100 to 8191.

    Increased MAXDEPTH (maximum depth of input stack) from 10 to 255.

    Increased interactive input buffer size from 1024 to 256k.  This has the
    effect of increasing the maximum length of an input line from a tty.
    This helps with an interactive bug that was reported by Ruslan Kabatsayev
    (b7 dot 10110111 at gmail dot com).
k
2018-03-04 11:09:09 -08:00
Landon Curt Noll
b29fcf2dd5 Fixed errors in various help files 2018-02-27 18:21:46 -08:00
Landon Curt Noll
4f86703843 Fix long lines 2018-02-27 16:16:06 -08:00
Landon Curt Noll
07d8bf0f3e Version 2.12.6.6 2018-02-21 12:38:39 -08:00
Landon Curt Noll
b4cd692bae Fixed compiler warnings
Fixed some compiler warnings.
Added work around for a gcc warning bug.
2018-02-21 12:37:46 -08:00
Landon Curt Noll
83c898cc2b Improved how lucas.cal pre-verifies numbers 2018-02-21 12:36:21 -08:00
Landon Curt Noll
c585d7aa78 Release calc version 2.12.6.5 2018-01-28 18:26:08 -08:00
Landon Curt Noll
f42a003d04 Improve formatting of comments in cal/lucas.cal 2018-01-16 15:33:00 -08:00
Landon Curt Noll
8da0471f07 Release calc version 2.12.6.4
Fixed a man page warning about ./myfile where the leading dot
was mistook for an nroff macro.  Thanks goes to David Haller
<dnh at opensuse dot org> for providing the patch.

Improved gen_v1(h,n) in lucas.cal for cases where h is not a
multiple of 3. Optimized the search for v(1) when h is a
multiple of 3.

Fixed a Makefile problem, reported by Doug Hays <doughays6 at gmail
dot com>, where if a macOS user set BINDIR, LIBDIR, CALC_SHAREDIR
or INCDIR in the top section, their values will be overwritten by
the Darwin specific section.
2018-01-16 15:27:13 -08:00
Landon Curt Noll
1c20261b93 Fixed macro warning about ./myfile 2017-09-07 14:28:54 -07:00
Landon Curt Noll
aeb9a9d473 Prepare for calc version 2.12.6.3 2017-09-06 18:20:35 -07:00
Landon Curt Noll
66883b390d Fixed CHANGES typo 2017-09-06 18:11:35 -07:00
Landon Curt Noll
ea533659ce Release calc version 2.12.6.2 2017-09-06 17:42:41 -07:00
Landon Curt Noll
9e81971f25 Verify that h*2^n-1 is not a multiple of 3 2017-09-06 17:41:56 -07:00
Landon Curt Noll
cbbd866535 Fixed a misleading indent reported by Thomas Walter 2017-09-06 17:40:49 -07:00
Landon Curt Noll
bf23f82c29 Correct comments relating to v(1) search table 2017-06-18 08:11:43 -07:00
Landon Curt Noll
ec5c584785 Fixed typo in lucas.cal comment 2017-06-18 04:11:44 -07:00
Landon Curt Noll
6bbb8c0e42 Update v(1) stats with full 1000000 test sample 2017-06-18 03:50:28 -07:00
Landon Curt Noll
438554b0ed Make a minor speedup to gen_v1(h,n) in lucas.cal 2017-06-14 16:50:58 -07:00
Landon Curt Noll
61ba4bc5c8 Improve lucas.cal v(1) search method & remarks 2017-06-14 16:30:42 -07:00
Landon Curt Noll
0145883396 Improved lucas.cal vt tables and arg checking 2017-06-09 15:44:48 -07:00
Landon Curt Noll
f91bfaab70 Prep for calc version 2.12.6.1 2017-06-05 21:05:25 -07:00
51 changed files with 1575 additions and 629 deletions

182
CHANGES
View File

@@ -1,4 +1,183 @@
The following are the changes from calc version 2.12.6.0 to date:
The following are the changes from calc version 2.12.7.1 to date:
Corrected CHANGES notes that were mixed up for TAB, VT, CR &
NL. The code in 2.12.7.0 is correct. The CHANGE notes should
have read:
The following is a partial list of escape sequences recognized
in strings and in printf formats:
\a audible bell byte 0x07 in ASCII encoding
\b backspace byte 0x08 in ASCII encoding
\f form feed byte 0x0c in ASCII encoding
\n newline byte 0x0a in ASCII encoding
\r return byte 0x0d in ASCII encoding
\t tab byte 0x09 in ASCII encoding
\v vertical tab byte 0x0b in ASCII encoding
Sorry!
The following are the changes from calc version 2.12.6.10: to 2.12.7.0:
Added a patch to replaces the manual search for include files
in $(INCDIR) in the have_*.h targets with compiler invocations.
Thanks goes to Helmut Grohne (helmut at subdivi dot de) who
implemented the patch and posted it to the Debian bug tracker
and Martin Buck (m at rtin-buck dor de) for forwarding it to us.
The check_include make rule was fixed to not assume /usr/include.
The qprintnum() function now takes outdigits as a 3rd argument.
Most of the time, this 3rd argument is just conf->outdigits.
But when it comes to the experimental '%g', this value can
change. This avoids having to modify conf->outdigits.
Fixed a problem where gcc complains about E_FUNC not being defined
for Linux systems as reported by Martin Buck (m at rtin-buck dor de).
Updated the help files help/config, help/display, help/epsilon,
help/fprint, help/printf, and help/strprintf to give more
examples of how display digits and epsilon precision interact
with displaying values.
Added more information about %g in the help file help/printf.
The '\a' is now recognized in a printf format string as the
single byte audible bell character (byte 0x07 in ASCII encoding).
The following is a partial list of escape sequences recognized
in strings and in printf formats:
\a audible bell byte 0x07 in ASCII encoding
\b backspace byte 0x08 in ASCII encoding
\f form feed byte 0x0c in ASCII encoding
\n newline byte 0x0a in ASCII encoding
\r return byte 0x0d in ASCII encoding
\t tab byte 0x09 in ASCII encoding
\v vertical tab byte 0x0b in ASCII encoding
The following are the changes from calc version 2.12.6.9 to 2.12.6.9:
Fixed a number of core dump bugs related to the calculation of
tan(), cot(), sec(), csc(), tanh(), coth(), sech(), and csch(),
asin(), acos(), asinh(), acosh(), where when a call to an
underlying function produced an invalid value. Thanks goes to
github user wuxiuheng for reporting this problem.
A number of trigonometric and hyperbolic functions that incorrectly
returned E_LOGINF, now return a new error code that is more
specific to the trigonometric or hyperbolic function. The
following is a list of these new error codes: E_TAN3 E_TAN4
E_COT3 E_COT4 E_SEC3 E_CSC3 E_TANH3 E_TANH4 E_COTH3 E_COTH4
E_SECH3 E_CSCH3 E_ASIN3 E_ACOS3 E_ASINH3 E_ACOSH3 E_ATAN3 E_ACOT3
E_ASEC3 E_ACSC3 E_ATANH3 E_ACOTH3 E_ASECH3 E_ACSCH3.
Added regression tests 3729 thru 3732 to test E_TAN3, E_COT3,
E_SEC3 and E_CSC3 respectively.
Added experimential %g printf (and strprintf) format implementation
based on pull request from github user 10110111.
Made exterimental changes to macOS builds to not require use of
/usr/include. The INCDIR for macOS uses:
INCDIR= $(shell xcrun --show-sdk-path --sdk macosx)/usr/include
to determine the upper path of the /usr/include directory for macOS.
In some rare cases, the Darwin target seems to not automatically detected.
If you are running under macOS, and that happens, you can force
the target to be Darwin:
# for macOS users only, force the target to be darwin
#
make target=Darwin clobber
make target=Darwin all
make target=Darwin chk
make target=Darwin install
The following are the changes from calc version 2.12.6.6 to 2.12.6.8:
For historical purposes, in lucas.cal, gen_v1(1, n) always returns 4.
Fixed some compiler warnings, thanks to a report by Mike
<michael dot d dot ince at gmail dot com>.
Added work around for a gcc warning bug, thanks to a report by Mike
<michael dot d dot ince at gmail dot com>.
Fixed errors in various help files such as:
mat randbit seed srandom types
Removed the MAXSTRING symbol because it was no longer used by calc.
Increased HIST_SIZE (depth of the history stack) from 10k to 32k.
Increased TTYSIZE (reallocation size for terminal buffers) from 100 to 8191.
Increased MAXDEPTH (maximum depth of input stack) from 10 to 255.
Increased interactive input buffer size from 1024 to 256k. This has the
effect of increasing the maximum length of an input line from a tty.
This helps with an interactive bug that was reported by Ruslan Kabatsayev
(b7 dot 10110111 at gmail dot com).
The calc man page indicates that -d also disables the printing of the
leading tilde.
Added information to "help command" about how to silence messages
while reading calc resource files.
Fixed an error message buffer overflow thanks to a report by
Frank Peters <nlp at northernlightsphoto dot biz>.
Replaced all use of the C funcion sprintf() with snprintf().
Replaced all use of the C funcion vsprintf() with vsnprintf().
Replaced all DONT_HAVE_VSPRINTF with DONT_HAVE_VSNPRINTF.
Replaced all Makefile var ${HAVE_VSPRINTF} with ${HAVE_VSNPRINTF}.
The following are the changes from calc version 2.12.6.4 to 2.12.6.5:
Fixed warning about undefined operations involving the qlink(q)
macro by replacing that macro with an inline-function. Thanks goes
to David Haller <dnh at opensuse dot org> for this fix.
NOTE for Windows 10 users: Pavel Nemec <pane at seznam dot cz>
reported that calc version 2.12.6.4 has been successfully
compiled, installed and running on Windows 10. See README.WINDOWS
for more details.
The following are the changes from calc version 2.12.6.1 to 2.12.6.3:
Improved gen_v1(h,n) in lucas.cal to use an even faster search method.
Improved are checking in lucas.cal. In particular both h and n must be
integers >= 1. In the case of both rodseth_xhn(x, h, n) and gen_v1(h, n)
h must be odd.
Fixed an C code indenting issue that was reported by Thomas Walter
<th dot walter42 at gmx dot de> in zfunc.c.
Fixed a man page warning about ./myfile where the leading dot
was mistook for an nroff macro. Thanks goes to David Haller
<dnh at opensuse dot org> for providing the patch.
Improved gen_v1(h,n) in lucas.cal for cases where h is not a
multiple of 3. Optimized the search for v(1) when h is a
multiple of 3.
Fixed a Makefile problem, reported by Doug Hays <doughays6 at gmail
dot com>, where if a macOS user set BINDIR, LIBDIR, CALC_SHAREDIR
or INCDIR in the top section, their values will be overwritten by
the Darwin specific section.
The following are the changes from calc version 2.12.6.0 to 2.12.6.0:
Added the makefile variable ${COMMON_ADD} that will add flags
to all compile and link commands. The ${COMMON_ADD} flags are
@@ -68,7 +247,6 @@ The following are the changes from calc version 2.12.6.0 to date:
Fixed a number of typos in the CHANGES file.
The following are the changes from calc version 2.12.5.4 to 2.12.5.6:
Recompile to match current RHEL7.2 libc and friends.

View File

@@ -32,6 +32,16 @@ Installing calc from the bzip2-ed tarball in 4 easy steps:
targets, the default make is sufficent. On FreeBSD for example,
one must use gmake instead of make.
Some report that under macOS, one has to declare the target
to be darwin. So for macOS, one might have to do:
# for macOS users only, force the target to be darwin
#
make target=Darwin clobber
make target=Darwin all
make target=Darwin chk
make target=Darwin install
If your target system does not have GNU Make (or equivalent), then
you should try using the Makefile.simple and custom/Makefile.simple
files:

View File

@@ -207,30 +207,9 @@ all: fix_version check_include
${V} echo '=-=-=-=-= private Makefile $@ rule end =-=-=-=-='
check_include:
$(Q) if [ ! -d /usr/include ]; then \
echo "ERROR: critical directory missing: /usr/include" 1>&2; \
echo "Without this critical directory, we cannot compile." 1>&2; \
echo 1>&2; \
echo "Perhaps your system isn't setup to compile C source?" 1>&2; \
echo "For example, Apple OS X / darwin requres that XCode" 1>&2; \
echo "must be installed and that you run the command:" 1>&2; \
echo 1>&2; \
echo " xcode-select --install" 1>&2; \
echo 1>&2; \
exit 1; \
fi
$(Q) if [ ! -f /usr/include/stdio.h ]; then \
echo "ERROR: critical include files are missing" 1>&2; \
echo "Without this critical directory, we cannot compile." 1>&2; \
echo 1>&2; \
echo "Perhaps your system isn't setup to compile C source?" 1>&2; \
echo "For example, Apple OS X / darwin requres that XCode" 1>&2; \
echo "must be installed and that you run the command:" 1>&2; \
echo 1>&2; \
echo " xcode-select --install" 1>&2; \
echo 1>&2; \
exit 1; \
fi
${V} echo '=-=-=-=-= private Makefile $@ rule start =-=-=-=-='
${Q} ${MAKE} ${XARG} -f ${MAKE_FILE} $@ ${XVAR}
${V} echo '=-=-=-=-= private Makefile $@ rule end =-=-=-=-='
calc-dynamic-only:
${V} echo '=-=-=-=-= private Makefile $@ rule start =-=-=-=-='

View File

@@ -23,7 +23,7 @@
# READLINE_LIB= -lreadline
# READLINE_EXTRAS= -lhistory -lncurses
#
# Copyright (C) 1999-2017 Landon Curt Noll
# Copyright (C) 1999-2018 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
@@ -90,29 +90,29 @@ TERMCONTROL=
#TERMCONTROL= -DUSE_SGTTY
#TERMCONTROL= -DUSE_WIN32
# If your system does not have a vsprintf() function, you could be in trouble.
# If your system does not have a vsnprintf() function, you could be in trouble.
#
# vsprintf(string, format, ap)
# vsnprintf(string, size, format, ap)
#
# This function works like sprintf except that the 3rd arg is a va_list
# strarg (or varargs) list. Some old systems do not have vsprintf().
# If you do not have vsprintf(), then calc will try sprintf() and hope
# This function works like spnrintf except that the 4th arg is a va_list
# strarg (or varargs) list. Some old systems do not have vsnprintf().
# If you do not have vsnprintf(), then calc will try snprintf() and hope
# for the best.
#
# A similar problem occurs if your system does not have a vsnprintf()
# function. This function is like the vsprintf() function except that
# function. This function is like the vsnprintf() function except that
# there is an extra second argument that controls the maximum size
# string that is produced.
#
# If HAVE_VSPRINTF is empty, this Makefile will run the have_stdvs.c and/or
# have_varvs.c program to determine if vsprintf() is supported. If
# HAVE_VSPRINTF is set to -DDONT_HAVE_VSPRINTF then calc will hope that
# sprintf() will work.
# If HAVE_VSNPRINTF is empty, this Makefile will run the have_stdvs.c and/or
# have_varvs.c program to determine if vsnprintf() is supported. If
# HAVE_VSNPRINTF is set to -DDONT_HAVE_VSNPRINTF then calc will hope that
# snprintf() will work.
#
# If in doubt, leave HAVE_VSPRINTF empty.
# If in doubt, leave HAVE_VSNPRINTF empty.
#
HAVE_VSPRINTF=
#HAVE_VSPRINTF= -DDONT_HAVE_VSPRINTF
HAVE_VSNPRINTF=
#HAVE_VSNPRINTF= -DDONT_HAVE_VSNPRINTF
# Determine the byte order of your machine
#
@@ -564,14 +564,30 @@ HAVE_UNUSED=
#
# INCDIR= /dev/env/DJDIR/include
#
# If in doubt, set:
# If in doubt, for non-macOS hosts set:
#
# INCDIR= /usr/include
#
# However, if you are on macOS then set:
#
# INCDIR= /usr/local/include
#if 0 /* start of skip for non-Gnu makefiles */
ifeq ($(target),Darwin)
# default INCDIR for macOS
INCDIR= $(shell xcrun --show-sdk-path --sdk macosx)/usr/include
else
#endif /* end of skip for non-Gnu makefiles */
# default INCDIR for non-macOS
INCDIR= /usr/include
#INCDIR= /usr/local/include
#INCDIR= /dev/env/DJDIR/include
INCDIR= /usr/include
#if 0 /* start of skip for non-Gnu makefiles */
endif
#endif /* end of skip for non-Gnu makefiles */
# Where to install calc related things
#
@@ -602,23 +618,71 @@ INCDIR= /usr/include
# LIBDIR= /dev/env/DJDIR/lib
# CALC_SHAREDIR= /dev/env/DJDIR/share/calc
#
# If in doubt, set:
# If in doubt, for non-macOS hosts set:
#
# BINDIR= /usr/bin
# LIBDIR= /usr/lib
# CALC_SHAREDIR= /usr/share/calc
#
# However, if you are on macOS then set:
#
# BINDIR= /usr/local/bin
# LIBDIR= /usr/local/lib
# CALC_SHAREDIR= /usr/local/share/calc
#
# NOTE: Starting with macOS El Capitan OS X 10.11, root by default
# could not mkdir under system locations, so macOS must now
# use the /usr/local tree.
#if 0 /* start of skip for non-Gnu makefiles */
ifeq ($(target),Darwin)
# default BINDIR for macOS
BINDIR= /usr/local/bin
else
#endif /* end of skip for non-Gnu makefiles */
# default BINDIR for non-macOS
BINDIR= /usr/bin
#BINDIR= /usr/local/bin
#BINDIR= /dev/env/DJDIR/bin
BINDIR= /usr/bin
#if 0 /* start of skip for non-Gnu makefiles */
endif
ifeq ($(target),Darwin)
# default LIBDIR for macOS
LIBDIR= /usr/local/lib
else
#endif /* end of skip for non-Gnu makefiles */
# default LIBDIR for non-macOS
LIBDIR= /usr/lib
#LIBDIR= /usr/local/lib
#LIBDIR= /dev/env/DJDIR/lib
LIBDIR= /usr/lib
#if 0 /* start of skip for non-Gnu makefiles */
endif
ifeq ($(target),Darwin)
# default CALC_SHAREDIR for macOS
CALC_SHAREDIR= /usr/local/share/calc
else
#endif /* end of skip for non-Gnu makefiles */
# default CALC_SHAREDIR for non-macOS
CALC_SHAREDIR= /usr/share/calc
#CALC_SHAREDIR= /usr/local/lib/calc
#CALC_SHAREDIR= /dev/env/DJDIR/share/calc
CALC_SHAREDIR= /usr/share/calc
#if 0 /* start of skip for non-Gnu makefiles */
endif
#endif /* end of skip for non-Gnu makefiles */
# NOTE: Do not set CALC_INCDIR to /usr/include or /usr/local/include!!!
# Always be sure that the CALC_INCDIR path ends in /calc to avoid
@@ -990,7 +1054,7 @@ EXT=
# The default calc versions
#
VERSION= 2.12.6.0
VERSION= 2.12.7.1
# Names of shared libraries with versions
#
@@ -1263,16 +1327,6 @@ LDCONFIG:=
# DARWIN_ARCH= -arch ppc # PPC binary
# DARWIN_ARCH= -arch x86_64 # native 64-bit binary
DARWIN_ARCH= # native binary
#
# Starting with El Capitan OS X 10.11, root by default could not
# mkdir under system locations, so we now use the /usr/local tree.
#
OPTDIR:= /usr/local
BINDIR:= /${OPTDIR}/bin
LIBDIR:= /${OPTDIR}/lib
CALC_SHAREDIR:= /${OPTDIR}/share
CALC_INCDIR:= /${OPTDIR}/include
SCRIPTDIR:= ${BINDIR}/cscript
endif
##################
@@ -2125,25 +2179,15 @@ TARGETS= ${EARLY_TARGETS} ${BLD_TYPE} ${LATE_TARGETS}
all: check_include ${BLD_TYPE} CHANGES
check_include:
$(Q) if [ ! -d /usr/include ]; then \
echo "ERROR: critical directory missing: /usr/include" 1>&2; \
echo "Without this critical directory, we cannot compile." 1>&2; \
echo 1>&2; \
$(Q) if ! echo '#include <stdio.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo "ERROR: Missing critical <stdio.h> include file." 1>&2; \
echo "Without critical include files, we cannot compile." 1>&2; \
echo "Perhaps your system isn't setup to compile C source?" 1>&2; \
echo "For example, Apple OS X / darwin requres that XCode" 1>&2; \
echo "must be installed and that you run the command:" 1>&2; \
echo 1>&2; \
echo " xcode-select --install" 1>&2; \
echo "For example, Apple macOS / Darwin requres that XCode" 1>&2; \
echo "must be installed." 1>&2; \
echo 1>&2; \
exit 1; \
fi
$(Q) if [ ! -f /usr/include/stdio.h ]; then \
echo "ERROR: critical include files are missing" 1>&2; \
echo "Without this critical directory, we cannot compile." 1>&2; \
echo 1>&2; \
echo "Perhaps your system isn't setup to compile C source?" 1>&2; \
echo "For example, Apple OS X / darwin requres that XCode" 1>&2; \
echo "must be installed and that you run the command:" 1>&2; \
echo "Also macOS users might later to run this command:" 1>&2; \
echo 1>&2; \
echo " xcode-select --install" 1>&2; \
echo 1>&2; \
@@ -2423,22 +2467,15 @@ endian_calc.h: endian${EXT} ${MAKE_FILE}
${Q} echo '' >> endian_calc.h
${Q} echo '/* what byte order are we? */' >> endian_calc.h
-${Q} if [ X"${CALC_BYTE_ORDER}" = X ]; then \
if [ -f ${INCDIR}/endian.h ]; then \
if echo '#include <endian.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '#include <endian.h>' >> endian_calc.h; \
echo '#define CALC_BYTE_ORDER BYTE_ORDER' >> endian_calc.h; \
elif [ -f ${INCDIR}/machine/endian.h ]; then \
elif echo '#include <machine/endian.h>' | \
${CC} -E - >/dev/null 2>&1; then \
echo '#include <machine/endian.h>' >> endian_calc.h; \
echo '#define CALC_BYTE_ORDER BYTE_ORDER' >> endian_calc.h; \
elif [ -f ${INCDIR}/sys/endian.h ]; then \
echo '#include <sys/endian.h>' >> endian_calc.h; \
echo '#define CALC_BYTE_ORDER BYTE_ORDER' >> endian_calc.h; \
elif [ -f /usr/include/endian.h ]; then \
echo '#include <endian.h>' >> endian_calc.h; \
echo '#define CALC_BYTE_ORDER BYTE_ORDER' >> endian_calc.h; \
elif [ -f /usr/include/machine/endian.h ]; then \
echo '#include <machine/endian.h>' >> endian_calc.h; \
echo '#define CALC_BYTE_ORDER BYTE_ORDER' >> endian_calc.h; \
elif [ -f /usr/include/sys/endian.h ]; then \
elif echo '#include <sys/endian.h>' | \
${CC} -E- >/dev/null 2>&1; then \
echo '#include <sys/endian.h>' >> endian_calc.h; \
echo '#define CALC_BYTE_ORDER BYTE_ORDER' >> endian_calc.h; \
else \
@@ -2505,9 +2542,7 @@ have_times.h: ${MAKE_FILE}
echo '#define HAVE_TIMES_H /* yes */' >> have_times.h; \
elif [ X"${HAVE_TIMES_H}" = X"NO" ]; then \
echo '#undef HAVE_TIMES_H /* no */' >> have_times.h; \
elif [ -f ${INCDIR}/times.h ]; then \
echo '#define HAVE_TIMES_H /* yes */' >> have_times.h; \
elif [ -f /usr/include/times.h ]; then \
elif echo '#include <times.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '#define HAVE_TIMES_H /* yes */' >> have_times.h; \
else \
echo '#undef HAVE_TIMES_H /* no */' >> have_times.h; \
@@ -2516,9 +2551,7 @@ have_times.h: ${MAKE_FILE}
echo '#define HAVE_SYS_TIMES_H /* yes */' >> have_times.h; \
elif [ X"${HAVE_SYS_TIMES_H}" = X"NO" ]; then \
echo '#undef HAVE_SYS_TIMES_H /* no */' >> have_times.h; \
elif [ -f ${INCDIR}/sys/times.h ]; then \
echo '#define HAVE_SYS_TIMES_H /* yes */' >> have_times.h; \
elif [ -f /usr/include/sys/times.h ]; then \
elif echo '#include <sys/times.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '#define HAVE_SYS_TIMES_H /* yes */' >> have_times.h; \
else \
echo '#undef HAVE_SYS_TIMES_H /* no */' >> have_times.h; \
@@ -2527,9 +2560,7 @@ have_times.h: ${MAKE_FILE}
echo '#define HAVE_TIME_H /* yes */' >> have_times.h; \
elif [ X"${HAVE_TIME_H}" = X"NO" ]; then \
echo '#undef HAVE_TIME_H /* no */' >> have_times.h; \
elif [ -f ${INCDIR}/time.h ]; then \
echo '#define HAVE_TIME_H /* yes */' >> have_times.h; \
elif [ -f /usr/include/time.h ]; then \
elif echo '#include <time.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '#define HAVE_TIME_H /* yes */' >> have_times.h; \
else \
echo '#undef HAVE_TIME_H /* no */' >> have_times.h; \
@@ -2538,9 +2569,7 @@ have_times.h: ${MAKE_FILE}
echo '#define HAVE_SYS_TIME_H /* yes */' >> have_times.h; \
elif [ X"${HAVE_SYS_TIME_H}" = X"NO" ]; then \
echo '#undef HAVE_SYS_TIME_H /* no */' >> have_times.h; \
elif [ -f ${INCDIR}/sys/time.h ]; then \
echo '#define HAVE_SYS_TIME_H /* yes */' >> have_times.h; \
elif [ -f /usr/include/sys/time.h ]; then \
elif echo '#include <sys/time.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '#define HAVE_SYS_TIME_H /* yes */' >> have_times.h; \
else \
echo '#undef HAVE_SYS_TIME_H /* no */' >> have_times.h; \
@@ -2576,9 +2605,7 @@ have_stdlib.h: ${MAKE_FILE}
echo '#define HAVE_STDLIB_H /* yes */' >> have_stdlib.h; \
elif [ X"${HAVE_STDLIB_H}" = X"NO" ]; then \
echo '#undef HAVE_STDLIB_H /* no */' >> have_stdlib.h; \
elif [ -f ${INCDIR}/stdlib.h ]; then \
echo '#define HAVE_STDLIB_H /* yes */' >> have_stdlib.h; \
elif [ -f /usr/include/stdlib.h ]; then \
elif echo '#include <stdlib.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '#define HAVE_STDLIB_H /* yes */' >> have_stdlib.h; \
else \
echo '#undef HAVE_STDLIB_H /* no */' >> have_stdlib.h; \
@@ -2614,9 +2641,7 @@ have_unistd.h: ${MAKE_FILE}
echo '#define HAVE_UNISTD_H /* yes */' >> have_unistd.h; \
elif [ X"${HAVE_UNISTD_H}" = X"NO" ]; then \
echo '#undef HAVE_UNISTD_H /* no */' >> have_unistd.h; \
elif [ -f ${INCDIR}/unistd.h ]; then \
echo '#define HAVE_UNISTD_H /* yes */' >> have_unistd.h; \
elif [ -f /usr/include/unistd.h ]; then \
elif echo '#include <unistd.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '#define HAVE_UNISTD_H /* yes */' >> have_unistd.h; \
else \
echo '#undef HAVE_UNISTD_H /* no */' >> have_unistd.h; \
@@ -2652,9 +2677,7 @@ have_string.h: ${MAKE_FILE}
echo '#define HAVE_STRING_H /* yes */' >> have_string.h; \
elif [ X"${HAVE_STRING_H}" = X"NO" ]; then \
echo '#undef HAVE_STRING_H /* no */' >> have_string.h; \
elif [ -f ${INCDIR}/string.h ]; then \
echo '#define HAVE_STRING_H /* yes */' >> have_string.h; \
elif [ -f /usr/include/string.h ]; then \
elif echo '#include <string.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '#define HAVE_STRING_H /* yes */' >> have_string.h; \
else \
echo '#undef HAVE_STRING_H /* no */' >> have_string.h; \
@@ -2694,22 +2717,12 @@ terminal.h: ${MAKE_FILE}
echo '#undef USE_TERMIOS /* <termios.h> */' >> terminal.h; \
echo '#undef USE_TERMIO /* <termio.h> */' >> terminal.h; \
echo '#undef USE_SGTTY /* <sys/ioctl.h> */' >> terminal.h; \
elif [ -f ${INCDIR}/termios.h ]; then \
elif echo '#include <termios.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '/* use termios */' >> terminal.h; \
echo '#define USE_TERMIOS /* <termios.h> */' >> terminal.h; \
echo '#undef USE_TERMIO /* <termio.h> */' >> terminal.h; \
echo '#undef USE_SGTTY /* <sys/ioctl.h> */' >> terminal.h; \
elif [ -f ${INCDIR}/termio.h ]; then \
echo '/* use termio */' >> terminal.h; \
echo '#undef USE_TERMIOS /* <termios.h> */' >> terminal.h; \
echo '#define USE_TERMIO /* <termio.h> */' >> terminal.h; \
echo '#undef USE_SGTTY /* <sys/ioctl.h> */' >> terminal.h; \
elif [ -f /usr/include/termios.h ]; then \
echo '/* use termios */' >> terminal.h; \
echo '#define USE_TERMIOS /* <termios.h> */' >> terminal.h; \
echo '#undef USE_TERMIO /* <termio.h> */' >> terminal.h; \
echo '#undef USE_SGTTY /* <sys/ioctl.h> */' >> terminal.h; \
elif [ -f /usr/include/termio.h ]; then \
elif echo '#include <termio.h>' | ${CC} -E - >/dev/null 2>&1; then \
echo '/* use termio */' >> terminal.h; \
echo '#undef USE_TERMIOS /* <termios.h> */' >> terminal.h; \
echo '#define USE_TERMIO /* <termio.h> */' >> terminal.h; \
@@ -3491,7 +3504,7 @@ args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h
${Q} echo '' >> args.h
${Q} echo '' >> args.h
${Q} ${RM} -f have_stdvs.o have_stdvs${EXT}
-${Q} ${LCC} ${ICFLAGS} ${HAVE_VSPRINTF} have_stdvs.c -c \
-${Q} ${LCC} ${ICFLAGS} ${HAVE_VSNPRINTF} have_stdvs.c -c \
>/dev/null 2>&1; ${TRUE}
-${Q} ${LCC} ${ILDFLAGS} have_stdvs.o -o have_stdvs${EXT} \
>/dev/null 2>&1; ${TRUE}
@@ -3500,10 +3513,10 @@ args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h
else \
${TRUE}; \
fi
-${Q} if [ ! -f have_args.sh ] && [ X"${HAVE_VSPRINTF}" = X ]; then \
-${Q} if [ ! -f have_args.sh ] && [ X"${HAVE_VSNPRINTF}" = X ]; then \
${RM} -f have_stdvs.o have_stdvs${EXT} have_varvs.o; \
${RM} -f have_varvs${EXT}; \
${LCC} ${ICFLAGS} ${HAVE_VSPRINTF} have_varvs.c -c \
${LCC} ${ICFLAGS} ${HAVE_VSNPRINTF} have_varvs.c -c \
2>/dev/null; \
${LCC} ${ILDFLAGS} have_varvs.o -o have_varvs${EXT} 2>/dev/null; \
if ./have_varvs${EXT} >>args.h 2>/dev/null; then \
@@ -3519,8 +3532,8 @@ args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h
else \
echo 'exit 1' > have_args.sh; \
echo "Unable to determine what type of variable args and"; \
echo "what type of vsprintf() should be used. Set or change"; \
echo "the Makefile variable HAVE_VSPRINTF."; \
echo "what type of vsnprintf() should be used. Set or change"; \
echo "the Makefile variable HAVE_VSNPRINTF."; \
fi
${Q} sh ./have_args.sh
${Q} echo '' >> args.h
@@ -4106,7 +4119,7 @@ env:
@echo 'HAVE_UNUSED=${HAVE_UNUSED}'; echo ''
@echo 'HAVE_URANDOM_H=${HAVE_URANDOM_H}'; echo ''
@echo 'HAVE_USTAT=${HAVE_USTAT}'; echo ''
@echo 'HAVE_VSPRINTF=${HAVE_VSPRINTF}'; echo ''
@echo 'HAVE_VSNPRINTF=${HAVE_VSNPRINTF}'; echo ''
@echo 'HELPDIR=${HELPDIR}'; echo ''
@echo 'HELP_PASSDOWN=${HELP_PASSDOWN}'; echo ''
@echo 'H_SRC=${H_SRC}'; echo ''

View File

@@ -10,6 +10,21 @@ NOTE: The main developers do not have access to a Windoz based platform.
Of course you are welcome to send us any patches that fix your
Windoz build environment.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= compiling with Windows Subsystem for Linux (WSL) =-Cygwin =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
It has been reported that calc version 2.12.6.4 has been successfully
compiled, installed and running on Windows 10 on 2018 Jan 21.
We were told:
"The Windows Subsystem for Linux (WSL) is a new Windows 10 feature that
enables you to run native Linux command-line tools directly on Windows"
https://docs.microsoft.com/cs-cz/windows/wsl/about
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= compiling with Cygwin =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

View File

@@ -1,7 +1,7 @@
/*
* lucas - perform a Lucas primality test on h*2^n-1
*
* Copyright (C) 1999,2017 Landon Curt Noll
* Copyright (C) 1999,2017,2018 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
@@ -28,6 +28,10 @@
* For a general tutorial on how to find a new largest known prime, see:
*
* http://www.isthe.com/chongo/tech/math/prime/prime-tutorial.pdf
*
* Also see the reference code, available both C and go:
*
* https://github.com/arcetri/goprime
*/
/*
@@ -154,6 +158,12 @@
*
* Finally, one should eliminate all values of 'h*2^n-1' where
* 'h*2^n+1' is divisible by a small primes.
*
* NOTE: Today, for world record sized h*2^n-1 primes, one might
* search for factors < 2^46 or more. By excluding h*2^n-1
* with prime factors < 2^46, where h*2^n-1 is a bit larger
* than the largest known prime, one may exclude about 96.5%
* of candidates that have "small" prime factors.
*/
pprod256 = 0; /* product of "primes up to 256" / "primes up to 46" */
@@ -243,8 +253,8 @@ pprod256 = 0; /* product of "primes up to 256" / "primes up to 46" */
* do make this so.
*
* input:
* h the h as in h*2^n-1
* n the n as in h*2^n-1
* h h as in h*2^n-1 (must be >= 1)
* n n as in h*2^n-1 (must be >= 1)
*
* returns:
* 1 => h*2^n-1 is prime
@@ -267,13 +277,17 @@ lucas(h, n)
* check arg types
*/
if (!isint(h)) {
ldebug("lucas", "h is non-int");
quit "FATAL: bad args: h must be an integer";
}
if (h < 1) {
quit "FATAL: bad args: h must be an integer >= 1";
}
if (!isint(n)) {
ldebug("lucas", "n is non-int");
quit "FATAL: bad args: n must be an integer";
}
if (n < 1) {
quit "FATAL: bad args: n must be an integer >= 1";
}
/*
* reduce h if even
@@ -359,41 +373,53 @@ lucas(h, n)
return 1; /* 239 is prime */
}
/*
* Verify that h*2^n-1 is not a multiple of 3
*
* The case for h*2^n-1 == 3 is handled above.
*/
if (((h % 3 == 1) && (n % 2 == 0)) || ((h % 3 == 2) && (n % 2 == 1))) {
/* no need to test h*2^n-1, it is a multiple of 3 */
ldebug("lucas","not-prime: != 3 and is a multiple of 3");
return 0;
}
/*
* Avoid any numbers divisible by small primes
*/
/*
* check for 3 <= prime factors < 29
* pfact(28)/2 = 111546435
* check for 5 <= prime factors < 31
* pfact(30)/6 = 1078282205
*/
testval = h*2^n - 1;
if (gcd(testval, 111546435) > 1) {
/* a small 3 <= prime < 29 divides h*2^n-1 */
ldebug("lucas","not-prime: 3<=prime<29 divides h*2^n-1");
if (gcd(testval, 1078282205) > 1) {
/* a small 5 <= prime < 31 divides h*2^n-1 */
ldebug("lucas",\
"not-prime: a small 5<=prime<31 divides h*2^n-1");
return 0;
}
/*
* check for 29 <= prime factors < 47
* pfact(46)/pfact(28) = 5864229
* check for 31 <= prime factors < 53
* pfact(52)/pfact(30) = 95041567
*/
if (gcd(testval, 58642669) > 1) {
/* a small 29 <= prime < 47 divides h*2^n-1 */
ldebug("lucas","not-prime: 29<=prime<47 divides h*2^n-1");
if (gcd(testval, 95041567) > 1) {
/* a small 31 <= prime < 53 divides h*2^n-1 */
ldebug("lucas","not-prime: 31<=prime<53 divides h*2^n-1");
return 0;
}
/*
* check for prime 47 <= factors < 257, if h*2^n-1 is large
* 2^282 > pfact(256)/pfact(46) > 2^281
* check for prime 53 <= factors < 257, if h*2^n-1 is large
* 2^276 > pfact(256)/pfact(52) > 2^275
*/
bits = highbit(testval);
if (bits >= 281) {
if (bits >= 275) {
if (pprod256 <= 0) {
pprod256 = pfact(256)/pfact(46);
pprod256 = pfact(256)/pfact(52);
}
if (gcd(testval, pprod256) > 1) {
/* a small 47 <= prime < 257 divides h*2^n-1 */
/* a small 53 <= prime < 257 divides h*2^n-1 */
ldebug("lucas",\
"not-prime: 47<=prime<257 divides h*2^n-1");
"not-prime: 53<=prime<257 divides h*2^n-1");
return 0;
}
}
@@ -409,7 +435,9 @@ lucas(h, n)
* generate a test for h*2^n-1. The legacy function,
* legacy_gen_v1() used by the Amdahl 6 could have returned
* -1. The new gen_v1() based on the method outlined in Ref4
* will never return -1.
* will never return -1 if h*2^n-1 is not a multiple of 3.
* Because the "multiple of 3" case is handled above, the
* call below to gen_v1() will never return -1.
*/
v1 = gen_v1(h, n);
if (v1 < 0) {
@@ -484,9 +512,9 @@ lucas(h, n)
* See the function gen_v1() for details on the value of v(1).
*
* input:
* h - h as in h*2^n-1
* n - n as in h*2^n-1
* v1 - gen_v1(h,n) (see function below)
* h - h as in h*2^n-1 (must be >= 1)
* n - n as in h*2^n-1 (must be >= 1)
* v1 - gen_v1(h,n) (must be >= 3) (see function below)
*
* returns:
* u(2) - initial value for Lucas test on h*2^n-1
@@ -499,6 +527,8 @@ gen_u2(h, n, v1)
local r; /* low value: v(n) */
local s; /* high value: v(n+1) */
local hbits; /* highest bit set in h */
local oldh; /* pre-reduced h */
local oldn; /* pre-reduced n */
local i;
/*
@@ -507,24 +537,45 @@ gen_u2(h, n, v1)
if (!isint(h)) {
quit "bad args: h must be an integer";
}
if (h < 0) {
quit "bad args: h must be an integer >= 1";
}
if (!isint(n)) {
quit "bad args: n must be an integer";
}
if (n < 1) {
quit "bad args: n must be an integer >= 1";
}
if (!isint(v1)) {
quit "bad args: v1 must be an integer";
}
if (v1 <= 0) {
quit "bogus arg: v1 is <= 0";
if (v1 < 3) {
quit "bogus arg: v1 must be an integer >= 3";
}
/*
* reduce h if even
*
* we will force h to be odd by moving powers of two over to 2^n
*/
oldh = h;
oldn = n;
shiftdown = fcnt(h,2); /* h % 2^shiftdown == 0, max shiftdown */
if (shiftdown > 0) {
h >>= shiftdown;
n += shiftdown;
}
/*
* enforce the h > 0 and n >= 2 rules
*/
if (h <= 0 || n < 1) {
print " ERROR: h=":oldh, "n=":oldn, "reduced h=":h, "n=":n;
quit "reduced args violate the rule: 0 < h < 2^n";
}
hbits = highbit(h);
if (hbits >= n) {
print " ERROR: h=":oldh, "n=":oldn, "reduced h=":h, "n=":n;
quit "reduced args violate the rule: 0 < h < 2^n";
}
@@ -599,8 +650,8 @@ gen_u2(h, n, v1)
* See the function gen_u2() for details.
*
* input:
* h - h as in h*2^n-1
* n - n as in h*2^n-1
* h - h as in h*2^n-1 (must be >= 1)
* n - n as in h*2^n-1 (must be >= 1)
* v1 - gen_v1(h,n) (see function below)
*
* returns:
@@ -638,9 +689,9 @@ gen_u0(h, n, v1)
* x > 2
*
* input:
* x - potential v(1) value
* h - h as in h*2^n-1
* n - n as in h*2^n-1
* x potential v(1) value
* h h as in h*2^n-1 (h must be odd >= 1)
* n n as in h*2^n-1 (must be >= 1)
*
* returns:
* 1 if v(1) == x for h*2^n-1
@@ -657,9 +708,18 @@ rodseth_xhn(x, h, n)
if (!isint(h)) {
quit "bad args: h must be an integer";
}
if (iseven(h)) {
quit "bad args: h must be an odd integer";
}
if (h < 1) {
quit "bad args: h must be an integer >= 1";
}
if (!isint(n)) {
quit "bad args: n must be an integer";
}
if (n < 1) {
quit "bad args: n must be an integer >= 1";
}
if (!isint(x)) {
quit "bad args: x must be an integer";
}
@@ -703,9 +763,9 @@ rodseth_xhn(x, h, n)
* We can show that X > 2. See the comments in the rodseth_xhn(x,h,n) above.
*
* Some values of X satisfy more often than others. For example a large sample
* of odd h, h multiple of 3 and large n (some around 1e4, some near 1e6, others
* near 3e7) where the sample size was 66 973 365, here is the count of the
* smallest value of X that satisfies conditions in Ref4, condition 1:
* of h*2^n-1, h odd multiple of 3, and large n (some around 1e4, some near 1e6,
* others near 3e7) where the sample size was 66 973 365, here is the count of
* the smallest value of X that satisfies conditions in Ref4, condition 1:
*
* count X
* ----------
@@ -763,45 +823,161 @@ rodseth_xhn(x, h, n)
* 1 161
* 1 155
*
* It is important that we select the smallest possible v(1). While testing
* various values of X for V(1) is fast, using larger than necessary values
* of V(1) of can slow down calculating V(h).
*
* The above distribution was found to hold fairly well over many values of
* odd h that are a multiple of 3 and for many values of n where h < 2^n.
* odd h that are also a multiple of 3 and for many values of n where h < 2^n.
*
* For example for in a sample size of 1000000 numbers of the form h*2^n-1
* where h is an odd multiple of 3, 12996351 <= h <= 13002351,
* 4331116 <= n <= 4332116, these are the smallest v(1) values that were found:
*
* smallest percentage
* v(1) used
* -------- ---------
* 3 40.0000 %
* 5 25.6833 %
* 9 11.6924 %
* 11 10.4528 %
* 15 4.8048 %
* 17 2.3458 %
* 21 1.3734 %
* 29 1.0527 %
* 20 0.8595 %
* 27 0.5758 %
* 35 0.4420 %
* 36 0.2433 %
* 39 0.1779 %
* 41 0.0885 %
* 45 0.0571 %
* 32 0.0337 %
* 51 0.0289 %
* 44 0.0205 %
* 49 0.0176 %
* 56 0.0137 %
* 59 0.0108 %
* 57 0.0053 %
* 65 0.0047 %
* 55 0.0045 %
* 69 0.0031 %
* 71 0.0024 %
* 66 0.0011 %
* 95 0.0008 %
* 81 0.0008 %
* 77 0.0006 %
* 72 0.0005 %
* 99 0.0004 %
* 80 0.0003 %
* 74 0.0003 %
* 84 0.0002 %
* 67 0.0002 %
* 87 0.0001 %
* 104 0.0001 %
* 129 0.0001 %
*
* However, a case can be made for considering only odd values for v(1)
* candidates. When h * 2^n-1 is prime and h is an odd multiple of 3,
* a smallest v(1) that is even is extremely rate. Of the list of 146553
* known primes of the form h*2^n-1 when h is an odd a multiple of 3,
* none has an smallest v(1) that was even.
*
* See:
*
* https://github.com/arcetri/verified-prime
*
* for that list of 146553 known primes of the form h*2^n-1.
*
* That same example for in a sample size of 1000000 numbers of the
* form h*2^n-1 where h is an odd multiple of 3, 12996351 <= h <= 13002351,
* 4331116 <= n <= 4332116, these are the smallest odd v(1) values that were
* found:
*
* smallest percentage
* odd v(1) used
* -------- ---------
* 3 40.0000 %
* 5 25.6833 %
* 9 11.6924 %
* 11 10.4528 %
* 15 4.8048 %
* 17 2.3458 %
* 21 1.6568 %
* 29 1.6174 %
* 35 0.4529 %
* 27 0.3546 %
* 39 0.3470 %
* 41 0.2159 %
* 45 0.1173 %
* 31 0.0661 %
* 51 0.0619 %
* 55 0.0419 %
* 59 0.0250 %
* 49 0.0170 %
* 69 0.0110 %
* 65 0.0098 %
* 71 0.0078 %
* 85 0.0048 %
* 81 0.0044 %
* 95 0.0038 %
* 99 0.0021 %
* 125 0.0009 %
* 57 0.0007 %
* 111 0.0005 %
* 77 0.0003 %
* 165 0.0003 %
* 155 0.0002 %
* 129 0.0002 %
* 101 0.0002 %
* 53 0.0001 %
*
* Moreover when evaluating odd candidates for v(1), one may cache Jacobi
* symbol evaluations to reduce the number of Jacobi symbol evaluations to
* a minimum. For example, if one tests 5 and finds that the 2nd case fails:
*
* jacobi(5+2, h*2^n-1) != -1
*
* Then if one is later testing 9, the Jacobi symbol value for the first
* 1st case:
*
* jacobi(7-2, h*2^n-1)
*
* is already known.
*
* Without Jacobi symbol value caching, it requires on average
* 4.851377 Jacobi symbol evaluations. With Jacobi symbol value caching
* cacheing, an averare of 4.348820 Jacobi symbol evaluations is needed.
*
* Given this information, when odd h is a multiple of 3 we try, in order,
* these values of X:
* these odd values of X:
*
* 3, 5, 9, 11, 15, 17, 21, 29, 20, 27, 35, 36, 39, 41, 45, 32, 51, 44,
* 56, 49, 59, 57, 65, 55, 69, 71, 77, 81, 66, 95, 80, 67, 84, 99, 72,
* 74, 87, 90, 104, 101, 105, 109, 116, 111, 92
* 3, 5, 9, 11, 15, 17, 21, 29, 27, 35, 39, 41, 31, 45, 51, 55, 49, 59,
* 69, 65, 71, 57, 85, 81, 95, 99, 77, 53, 67, 125, 111, 105, 87, 129,
* 101, 83, 165, 155, 149, 141, 121, 109
*
* And stop on the first value of X where:
*
* jacobi(X-2, h*2^n-1) == 1
* jacobi(X+2, h*2^n-1) == -1
*
* If no value in that list works, we start simple search starting with X = 120
* and incrementing by 1 until a value of X is found.
* Less than 1 case out of 1000000 will not be satisifed by the above list.
* If no value in that list works, we start simple search starting with X = 167
* and incrementing by 2 until a value of X is found.
*
* The x_tbl[] matrix contains those common values of X to try in order.
* If all x_tbl_len fail to satisfy Ref4 condition 1, then we begin a
* linear search at next_x until we find a proper X value.
*
* IMPORTANT NOTE: Using this table will not find the smallest possible v(1)
* for a given h and n. This is not a problem because using
* a larger value of v(1) does not impact the primality test.
* Furthermore after lucas(h, n) generates a few u(n) terms,
* the values will wrap (due to computing mod h*2^n-1).
* Finally on average, about 1/4 of the values of X work as
* v(1) for a given n when h is a multiple of 3. Skipping
* rarely used v(1) will not doom gen_v1() to a long search.
* The x_tbl[] matrix contains those values of X to try in order.
* If all x_tbl_len fail to satisfy Ref4 condition 1 (this happens less than
* 1 in 1000000 cases), then we begin a linear search of odd values starting at
* next_x until we find a proper X value.
*/
x_tbl_len = 45;
x_tbl_len = 42;
mat x_tbl[x_tbl_len];
x_tbl = {
3, 5, 9, 11, 15, 17, 21, 29, 20, 27, 35, 36, 39, 41, 45, 32, 51, 44,
56, 49, 59, 57, 65, 55, 69, 71, 77, 81, 66, 95, 80, 67, 84, 99, 72,
74, 87, 90, 104, 101, 105, 109, 116, 111, 92
3, 5, 9, 11, 15, 17, 21, 29, 27, 35, 39, 41, 31, 45, 51, 55, 49, 59,
69, 65, 71, 57, 85, 81, 95, 99, 77, 53, 67, 125, 111, 105, 87, 129,
101, 83, 165, 155, 149, 141, 121, 109
};
next_x = 120;
next_x = 167; /* must be 2 more than the largest value in x_tbl[] */
/*
* gen_v1 - compute the v(1) for a given h*2^n-1 if we can
@@ -859,12 +1035,22 @@ next_x = 120;
*
* u(2) = v(h) (NOTE: some call this u(2))
*
* so we simply return
* so we can always return
*
* v(1) = alpha^1 + alpha^(-1)
* = (2+sqrt(3)) + (2-sqrt(3))
* = 4
*
* In 40% of the cases when h is not a multiple of 3, 3 is a valid value
* for v(1). We can test if 3 is a valid value for v(1) in this case:
*
* if jacobi(1, h*2^n-1) == 1 and jacobi(5, h*2^n-1) == -1, then
* v(1) = 3
* else
* v(1) = 4
*
* HOTE: The above "if then else" works only of h is not a multiple of 3.
*
***
*
* Case 2: (h mod 3 == 0)
@@ -956,17 +1142,22 @@ next_x = 120;
***
*
* input:
* h h as in h*2^n-1
* n n as in h*2^n-1
* h h as in h*2^n-1 (h must be odd >= 1)
* n n as in h*2^n-1 (must be >= 1)
*
* output:
* returns v(1), or -1 is there is no quick way
* returns v(1), or
* -1 when h*2^n-1 is a multiple of 3
*/
define
gen_v1(h, n)
{
local x; /* potential v(1) to test */
local i; /* x_tbl index */
local v1m2; /* X-2 1st case */
local v1p2; /* X+2 2nd case */
local testval; /* h*2^n-1 - value we are testing if prime */
local mat cached_v1[next_x]; /* cached Jacobi symbol values or 0 */
/*
* check arg types
@@ -974,58 +1165,131 @@ gen_v1(h, n)
if (!isint(h)) {
quit "bad args: h must be an integer";
}
if (iseven(h)) {
quit "bad args: h must be an odd integer";
}
if (h < 1) {
quit "bad args: h must be an integer >= 1";
}
if (!isint(n)) {
quit "bad args: n must be an integer";
}
if (n < 1) {
quit "bad args: n must be an integer >= 1";
}
/*
* pretest: Verify that h*2^n-1 is not a multiple of 3
*/
if (((h % 3 == 1) && (n % 2 == 0)) || ((h % 3 == 2) && (n % 2 == 1))) {
/* no need to test h*2^n-1, it is not prime */
return -1;
}
/*
* Common Mersenne number case:
*
* For Mersenne numbers:
*
* 2^n-1
*
* we can use, 40% of the time, v(1) == 3. However nearly all code that
* implements the Lucas-Lehmer test uses v(1) == 4. Whenever for
* h != 0 mod 3, and particular the Mersenne number case of when h == 1:
*
* 1*2^n-1
*
* v(1) == 4 always works. For this reason, we return 4 when h == 1.
*/
if (h == 1) {
/* v(1) == 4 always works for the Mersenne number case */
return 4;
}
/*
* check for Case 1: (h mod 3 != 0)
*/
if (h % 3 != 0) {
/* v(1) is easy to compute */
return 4;
if (rodseth_xhn(3, h, n) == 1) {
/* 40% of the time, 3 works when h mod 3 != 0 */
return 3;
} else {
/* otherwise 4 always works when h mod 3 != 0 */
return 4;
}
}
/*
* What follow is Case 2: (h mod 3 == 0)
*/
/*
* clear cache
*/
matfill(cached_v1, 0);
/*
* We will look for x that satisfies conditions in Ref4, condition 1:
*
* jacobi(X-2, h*2^n-1) == 1 part 1
* jacobi(X+2, h*2^n-1) == -1 part 2
*
* NOTE: If we wanted to be super optimial, we would cache
* jacobi(X+2, h*2^n-1) that that when we increment X
* to the next odd value, the now jacobi(X-2, h*2^n-1)
* does not need to be re-evaluted.
*/
testval = h*2^n-1;
for (i=0; i < x_tbl_len; ++i) {
/*
* test Ref4 condition 1:
* obtain the next test candidate
*/
x = x_tbl[i];
if (rodseth_xhn(x, h, n) == 1) {
/*
* found a x that satisfies Ref4 condition 1
*/
ldebug("gen_v1", "h= " + str(h) + " n= " + str(n) +
" v1= " + str(x) + " using tbl[ " +
str(i) + " ]");
return x;
/*
* Check x for condition 1 part 1
*
* jacobi(x-2, h*2^n-1) == 1
*/
v1m2 = x-2;
if (cached_v1[v1m2] == 0) {
cached_v1[v1m2] = jacobi(v1m2, testval);
}
if (cached_v1[v1m2] != 1) {
continue;
}
/*
* Check x for condition 1 part 2
*
* jacobi(x+2, h*2^n-1) == -1
*/
v1p2 = x+2;
if (cached_v1[v1p2] == 0) {
cached_v1[v1p2] = jacobi(v1p2, testval);
}
if (cached_v1[v1p2] != -1) {
continue;
}
/*
* found a x that satisfies Ref4 condition 1
*/
ldebug("gen_v1", "h= " + str(h) + " n= " + str(n) +
" v1= " + str(x) + " using tbl[ " +
str(i) + " ]");
return x;
}
/*
* We are in that rare case (about 1 in 2 300 000) where none of the
* We are in that rare case (less than 1 in 1 000 000) where none of the
* common X values satisfy Ref4 condition 1. We start a linear search
* at next_x from here on.
*
* However, we also need to keep in mind that when x+2 >= 257, we
* need to verify that gcd(x-2, h*2^n-1) == 1 and
* and to verify that gcd(x+2, h*2^n-1) == 1.
* of odd vules at next_x from here on.
*/
x = next_x;
while (rodseth_xhn(x, h, n) != 1) {
++x;
x += 2;
}
/* finally found a v(1) value */
ldebug("gen_v1", "h= " + str(h) + " n= " + str(n) +
@@ -1457,8 +1721,8 @@ legacy_d_qval[7] = 19; legacy_v1_qval[7] = 74; /* a=38 b=1 r=2 */
***
*
* input:
* h h as in h*2^n-1
* n n as in h*2^n-1
* h h as in h*2^n-1 (must be >= 1)
* n n as in h*2^n-1 (must be >= 1)
*
* output:
* returns v(1), or -1 is there is no quick way
@@ -1470,6 +1734,22 @@ legacy_gen_v1(h, n)
local val_mod; /* h*2^n-1 mod 'D' */
local i;
/*
* check arg types
*/
if (!isint(h)) {
quit "bad args: h must be an integer";
}
if (h < 1) {
quit "bad args: h must be an integer >= 1";
}
if (!isint(n)) {
quit "bad args: n must be an integer";
}
if (n < 1) {
quit "bad args: n must be an integer >= 1";
}
/*
* check for case 1
*/

View File

@@ -3227,9 +3227,9 @@ define test_error()
print '3600: Beginning test_error';
/* bump ecnt up by 148 */
ecnt += 148;
print '3601: ecnt += 148';
/* bump ecnt up by 156 */
ecnt += 156;
print '3601: ecnt += 156';
strx = "x";
print '3602: strx = "x"';
@@ -3418,11 +3418,15 @@ define test_error()
n = 8191;
print '3727: n = 8191';
/* test 3728 removed due to non-portable strerror() output */
vrfy(tan(2e9i) == error(10435), '3729: tan(2e9i) == error(10435)');
vrfy(cot(2e9i) == error(10437), '3730: cot(2e9i) == error(10437)');
vrfy(sec(2e9i) == error(10439), '3731: sec(2e9i) == error(10439)');
vrfy(csc(2e9i) == error(10440), '3732: csc(2e9i) == error(10440)');
/* errmax and errcount should be bumped up the 148 errors above */
vrfy(errcount() == ecnt, '3729: errcount() == ecnt');
vrfy(errcount() == ecnt, '3733: errcount() == ecnt');
print '3730: Ending test_error';
print '3734: Ending test_error';
}
print '054: parsed test_error()';
@@ -4102,38 +4106,46 @@ define test_strprintf()
'4821: strprintf("%b", 27/29) == "0b11011/0b11101"');
vrfy(strprintf("%e", 12345) == "~1.23e4",
'4822: strprintf("%e", 12345) == "~1.23e4"');
vrfy(strprintf("%g", .385) == "~.38",
'4823: strprintf("%g", .385) == "~.38"');
vrfy(strprintf("%g", 385) == "~3.8e2",
'4824: strprintf("%g", 385) == "~3.8e2"');
/* mode tests with tilde == 0 */
c = config("tilde", 0);
print '4823: c = config("tilde", 0)';
print '4825: c = config("tilde", 0)';
vrfy(strprintf("%e", 12345) == "1.23e4",
'4824: strprintf("%e", 12345) == "1.23e4"');
'4826: strprintf("%e", 12345) == "1.23e4"');
vrfy(strprintf("%.3e", 12345) == "1.234e4",
'4825: strprintf("%.3e", 12345) == "1.234e4"');
'4827: strprintf("%.3e", 12345) == "1.234e4"');
vrfy(strprintf("%e", .00012345) == "1.23e-4",
'4826: strprintf("%e", .00012345) == "1.23e-4"');
'4828: strprintf("%e", .00012345) == "1.23e-4"');
vrfy(strprintf("%d %d", 27) == "27 ",
'4827: strprintf("%d %d", 27) == "27 "');
'4829: strprintf("%d %d", 27) == "27 "');
vrfy(strprintf("%d", 27, 29) == "27",
'4828: strprintf("%d", 27, 29) == "27"');
'4830: strprintf("%d", 27, 29) == "27"');
vrfy(strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93",
'4829: strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93"');
'4831: strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93"');
vrfy(strprintf("%s", "abc") == "abc",
'4830: strprintf("%s", "abc") == "abc"');
'4832: strprintf("%s", "abc") == "abc"');
vrfy(strprintf("%f", "abc") == "abc",
'4831: strprintf("%f", "abc") == "abc"');
'4833: strprintf("%f", "abc") == "abc"');
vrfy(strprintf("%e", "abc") == "abc",
'4832: strprintf("%e", "abc") == "abc"');
'4834: strprintf("%e", "abc") == "abc"');
vrfy(strprintf("%5s", "abc") == " abc",
'4833: strprintf("%5s", "abc") == " abc"');
'4835: strprintf("%5s", "abc") == " abc"');
vrfy(strprintf("%-5s", "abc") == "abc ",
'4834: strprintf("%-5s", "abc") == "abc "');
'4836: strprintf("%-5s", "abc") == "abc "');
vrfy(strprintf("%g", .385) == ".38",
'4837: strprintf("%g", .385) == ".38"');
vrfy(strprintf("%g", 385) == "3.8e2",
'4838: strprintf("%g", 385) == "3.8e2"');
/* restore config */
c = config("all", callcfg);
print '4835: c = config("all", callcfg)';
print '4839: c = config("all", callcfg)';
print '4836: Ending test_strprintf';
print '4840: Ending test_strprintf';
}
print '088: parsed test_fileop()';
@@ -7932,8 +7944,8 @@ print '8901: read -once "test8900"';
read -once "test8900";
print '8902: about to run test8900(1,,8903)';
testnum = test8900(1,,8903);
print '8999: ecnt = 203;'
ecnt = 203;
print '8999: ecnt = 211;'
ecnt = 211;
/* 89xx: test calc resource functions by Christoph Zurnieden */

19
calc.c
View File

@@ -104,6 +104,8 @@ main(int argc, char **argv)
int c; /* option */
int index;
int maxindex;
/* fix gcc warning bug */
int unusedint = 0;
char *cp;
char *endcp;
char *bp;
@@ -278,7 +280,9 @@ main(int argc, char **argv)
exit(6);
}
calc_debug = cp;
(void) strtol(cp, &endcp, 10);
/* fix gcc warning bug */
unusedint =
strtol(cp, &endcp, 10);
cp = endcp;
if (*cp != '\0' &&
*cp != ' ' && *cp != ':') {
@@ -310,7 +314,9 @@ main(int argc, char **argv)
exit(9);
}
resource_debug = cp;
(void) strtol(cp, &endcp, 10);
/* fix gcc warning bug */
unusedint =
strtol(cp, &endcp, 10);
cp = endcp;
if (*cp != '\0' &&
*cp != ' ' && *cp != ':') {
@@ -340,7 +346,8 @@ main(int argc, char **argv)
exit(12);
}
user_debug = cp;
(void) strtol(cp, &endcp, 10);
/* unusedint avoids gcc warning bug */
unusedint = strtol(cp, &endcp, 10);
cp = endcp;
if (*cp != '\0' && *cp != ' ') {
fprintf(stderr, "Bad syntax in"
@@ -721,8 +728,10 @@ main(int argc, char **argv)
printf("main: run_state = %s\n", run_state_name(run_state));
/*
* all done
* All done! - Jessica Noll, Age 2
*/
/* fix gcc warning bug */
unusedint++;
libcalc_call_me_last();
return (run_state == RUN_EXIT_WITH_ERROR ||
run_state == RUN_ZERO) ? 1 : 0;
@@ -766,7 +775,7 @@ calc_interrupt(char *fmt, ...)
va_start(ap, fmt);
vsnprintf(calc_err_msg, MAXERROR, fmt, ap);
va_end(ap);
calc_err_msg[MAXERROR] = '\0';
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
fprintf(stderr, "%s\n\n", calc_err_msg);
funcname = NULL;
if (calc_use_scanerr_jmpbuf != 0) {

1
calc.h
View File

@@ -65,7 +65,6 @@
#define SYMBOLSIZE 256 /* maximum symbol name size */
#define MAXLABELS 100 /* maximum number of user labels in function */
#define MAXSTRING 1024 /* maximum size of string constant */
#define MAXSTACK 2048 /* maximum depth of evaluation stack */
#define MAXFILES 20 /* maximum number of opened files */
#define PROMPT1 "> " /* default normal prompt*/

View File

@@ -1,5 +1,5 @@
.\"
.\" Copyright (C) 1999-2007,2014 Landon Curt Noll
.\" Copyright (C) 1999-2007,2014,2018 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
@@ -138,7 +138,7 @@ calc -d "read qtime; qtime(2)"
.fi
.in -5n
.sp 1
will just say:
will just print:
.sp 1
.in +5n
.nf
@@ -148,6 +148,41 @@ It's nearly ten past six.
.sp 1
This flag disables the reporting of missing calc
startup resource files.
.sp 1
This flag also disables the printing the leading tilde. For example:
.sp 1
.in +5n
.nf
calc 2/3
.fi
.in -5n
.sp 1
will print:
.sp 1
.in +5n
.nf
~0.66666666666666666667
.fi
.in -5n
.sp 1
.sp 1
whereas:
.sp 1
.in +5n
.nf
calc -d 2/3
.fi
.in -5n
.sp 1
will just print:
.sp 1
.in +5n
.nf
0.66666666666666666667
.fi
.in -5n
.sp 1
.TP
.BR -D " calc_debug[:resource_debug[:user_debug]]"
@@ -657,8 +692,8 @@ searches in succession:
.sp 1
.in +5n
.nf
./myfile
./myfile.cal
\a./myfile
\a./myfile.cal
${LIBDIR}/myfile
${LIBDIR}/myfile.cal
${CUSTOMCALDIR}/myfile

View File

@@ -451,6 +451,7 @@ E_FPATHOPEN1 Non-string arguments for fpathopen
E_FPATHOPEN2 Unrecognized mode for fpathopen
E_LOG1 Bad epsilon argument for log
E_LOG2 Non-numeric first argument for log
E_LOG3 Cannot calculate log for this value
E_FGETFILE1 Non-file argument for fgetfile
E_FGETFILE2 File argument for fgetfile not open for reading
E_FGETFILE3 Unable to set file position in fgetfile
@@ -471,3 +472,27 @@ E_ISSPACE Bad argument for isspace
E_ISXDIGIT Bad argument for isxdigit
E_STRTOUPPER Bad argument type for strtoupper
E_STRTOLOWER Bad argument type for strtolower
E_TAN3 Invalid value for calculating the sin numerator for tan
E_TAN4 Invalid value for calculating the cos denominator for tan
E_COT3 Invalid value for calculating the sin numerator for cot
E_COT4 Invalid value for calculating the cos denominator for cot
E_SEC3 Invalid value for calculating the cos reciprocal for sec
E_CSC3 Invalid value for calculating the sin reciprocal for csc
E_TANH3 Invalid value for calculating the sinh numerator for tanh
E_TANH4 Invalid value for calculating the cosh denominator for tanh
E_COTH3 Invalid value for calculating the sinh numerator for coth
E_COTH4 Invalid value for calculating the cosh denominator for coth
E_SECH3 Invalid value for calculating the cosh reciprocal for sech
E_CSCH3 Invalid value for calculating the sinh reciprocal for csch
E_ASIN3 Invalid value for calculating asin
E_ACOS3 Invalid value for calculating acos
E_ASINH3 Invalid value for calculating asinh
E_ACOSH3 Invalid value for calculating acosn
E_ATAN3 Invalid value for calculating atan
E_ACOT3 Invalid value for calculating acot
E_ASEC3 Invalid value for calculating asec
E_ACSC3 Invalid value for calculating acsc
E_ATANH3 Invalid value for calculating atan
E_ACOTH3 Invalid value for calculating acot
E_ASECH3 Invalid value for calculating asec
E_ACSCH3 Invalid value for calculating acsc

View File

@@ -1182,7 +1182,7 @@ comprint(COMPLEX *c)
return;
}
if (!qiszero(c->real) || qiszero(c->imag))
qprintnum(c->real, MODE_DEFAULT);
qprintnum(c->real, MODE_DEFAULT, conf->outdigits);
qtmp = c->imag[0];
if (qiszero(&qtmp))
return;
@@ -1192,7 +1192,7 @@ comprint(COMPLEX *c)
math_chr('-');
qtmp.num.sign = 0;
}
qprintnum(&qtmp, MODE_DEFAULT);
qprintnum(&qtmp, MODE_DEFAULT, conf->outdigits);
math_chr('i');
}

View File

@@ -274,6 +274,7 @@ STATIC NAMETYPE modes[] = {
{"oct", MODE_OCTAL},
{"binary", MODE_BINARY},
{"bin", MODE_BINARY},
{"float-auto", MODE_REAL_AUTO},
{"off", MODE2_OFF},
{NULL, 0}
};

View File

@@ -1,7 +1,7 @@
/*
* custom - interface for custom software and hardware interfaces
*
* Copyright (C) 1999-2006 Landon Curt Noll
* Copyright (C) 1999-2006,2018 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
@@ -180,6 +180,7 @@ customhelp(char *name)
#if defined(CUSTOM)
char *customname; /* a string of the form: custom/name */
size_t snprintf_len; /* malloced snprintf buffer length */
/*
* firewall
@@ -191,12 +192,14 @@ customhelp(char *name)
/*
* form the custom help name
*/
customname = (char *)malloc(sizeof("custhelp")+1+strlen(name)+1);
snprintf_len = sizeof("custhelp")+1+strlen(name)+1;
customname = (char *)malloc(snprintf_len+1);
if (customname == NULL) {
math_error("bad malloc of customname");
/*NOTREACHED*/
}
sprintf(customname, "custhelp/%s", name);
snprintf(customname, snprintf_len, "custhelp/%s", name);
customname[snprintf_len] = '\0'; /* paranoia */
/*
* give help directly to the custom file

View File

@@ -2,7 +2,7 @@
#
# custom - makefile for calc custom routines
#
# Copyright (C) 1999-2006,2014,2017 Landon Curt Noll
# Copyright (C) 1999-2006,2014,2017-2018 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
@@ -348,7 +348,7 @@ EXT=
# The default calc versions
#
VERSION= 2.12.6.0
VERSION= 2.12.7.1
# Names of shared libraries with versions
#
@@ -628,16 +628,6 @@ LDCONFIG:=
# DARWIN_ARCH= -arch ppc # PPC binary
# DARWIN_ARCH= -arch x86_64 # native 64-bit binary
DARWIN_ARCH= # native binary
#
# Starting with El Capitan OS X 10.11, root by default could not
# mkdir under system locations, so we now use the /usr/local tree.
#
OPTDIR:= /usr/local
BINDIR:= /${OPTDIR}/bin
LIBDIR:= /${OPTDIR}/lib
CALC_SHAREDIR:= /${OPTDIR}/share
CALC_INCDIR:= /${OPTDIR}/include
SCRIPTDIR:= ${BINDIR}/cscript
endif
##################

View File

@@ -2,7 +2,7 @@
#
# custom - makefile for calc custom routines
#
# Copyright (C) 1999-2006,2014,2017 Landon Curt Noll
# Copyright (C) 1999-2006,2014,2017-2018 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
@@ -348,7 +348,7 @@ EXT=
# The default calc versions
#
VERSION= 2.12.6.0
VERSION= 2.12.7.1
# Names of shared libraries with versions
#

View File

@@ -173,8 +173,6 @@ STATIC struct infoname sys_info[] = {
(FULL)MAXSCANCOUNT},
{"MAXSTACK", "max depth of evaluation stack", NULL,
(FULL)MAXSTACK},
{"MAXSTRING", "max size of string constant", NULL,
(FULL)MAXSTRING},
{"MAXUFULL", "largest FULL value", NULL,
(FULL)MAXUFULL},
{"MAXULONG", "largest unsigned long val", NULL,

13
file.c
View File

@@ -1,7 +1,7 @@
/*
* file - file I/O routines callable by users
*
* Copyright (C) 1999-2007 David I. Bell and Landon Curt Noll
* Copyright (C) 1999-2007,2018 David I. Bell and Landon Curt Noll
*
* Primary author: David I. Bell
*
@@ -143,6 +143,7 @@ file_init(void)
* stat the descriptor to see what we have
*/
if (fstat(i, &sbuf) >= 0) {
size_t snprintf_len; /* malloced snprintf length */
fp = (FILE *) fdopen(i,"r+"); /*guess mode*/
if (fp) {
strcpy(files[idnum].mode, "r+");
@@ -161,12 +162,15 @@ file_init(void)
continue;
}
}
tname = (char *)malloc(sizeof("descriptor[19]"));
snprintf_len =
sizeof("descriptor[12345678901234567890]") + 1;
tname = (char *)malloc(snprintf_len+1);
if (tname == NULL) {
math_error("Out of memory for init_file");
/*NOTREACHED*/
}
sprintf(tname, "descriptor[%d]", i);
snprintf(tname, snprintf_len, "descriptor[%d]", i);
tname[snprintf_len] = '\0'; /* paranoia */
files[idnum].name = tname;
files[idnum].id = idnum;
files[idnum].fp = fp;
@@ -1027,6 +1031,9 @@ idprintf(FILEID id, char *fmt, int count, VALUE **vals)
case 'e':
newmode = MODE_EXP;
break;
case 'g':
newmode = MODE_REAL_AUTO;
break;
case 'r':
newmode = MODE_FRAC;
break;

121
func.c
View File

@@ -1,7 +1,7 @@
/*
* func - built-in functions implemented here
*
* Copyright (C) 1999-2007 David I. Bell, Landon Curt Noll and Ernest Bowen
* Copyright (C) 1999-2007,2018 David I. Bell, Landon Curt Noll & Ernest Bowen
*
* Primary author: David I. Bell
*
@@ -335,7 +335,7 @@ f_str(VALUE *vp)
break;
case V_NUM:
math_divertio();
qprintnum(vp->v_num, MODE_DEFAULT);
qprintnum(vp->v_num, MODE_DEFAULT, conf->outdigits);
cp = math_getdivertedio();
result.v_str = makestring(cp);
break;
@@ -2122,6 +2122,9 @@ f_log(int count, VALUE **vals)
default:
return error_value(E_LOG2);
}
if (c == NULL) {
return error_value(E_LOG3);
}
result.v_type = V_COM;
result.v_com = c;
if (cisreal(c)) {
@@ -2239,8 +2242,15 @@ f_tan(int count, VALUE **vals)
case V_COM:
tmp1.v_type = V_COM;
tmp1.v_com = c_sin(vals[0]->v_com, err);
if (tmp1.v_com == NULL) {
return error_value(E_TAN3);
}
tmp2.v_type = V_COM;
tmp2.v_com = c_cos(vals[0]->v_com, err);
if (tmp2.v_com == NULL) {
comfree(tmp1.v_com);
return error_value(E_TAN4);
}
divvalue(&tmp1, &tmp2, &result);
comfree(tmp1.v_com);
comfree(tmp2.v_com);
@@ -2276,6 +2286,9 @@ f_sec(int count, VALUE **vals)
case V_COM:
tmp.v_type = V_COM;
tmp.v_com = c_cos(vals[0]->v_com, err);
if (tmp.v_com == NULL) {
return error_value(E_SEC3);
}
invertvalue(&tmp, &result);
comfree(tmp.v_com);
break;
@@ -2314,8 +2327,15 @@ f_cot(int count, VALUE **vals)
case V_COM:
tmp1.v_type = V_COM;
tmp1.v_com = c_cos(vals[0]->v_com, err);
if (tmp1.v_com == NULL) {
return error_value(E_COT3);
}
tmp2.v_type = V_COM;
tmp2.v_com = c_sin(vals[0]->v_com, err);
if (tmp2.v_com == NULL) {
comfree(tmp1.v_com);
return error_value(E_COT4);
}
divvalue(&tmp1, &tmp2, &result);
comfree(tmp1.v_com);
comfree(tmp2.v_com);
@@ -2354,6 +2374,9 @@ f_csc(int count, VALUE **vals)
case V_COM:
tmp.v_type = V_COM;
tmp.v_com = c_sin(vals[0]->v_com, err);
if (tmp.v_com == NULL) {
return error_value(E_CSC3);
}
invertvalue(&tmp, &result);
comfree(tmp.v_com);
break;
@@ -2476,8 +2499,15 @@ f_tanh(int count, VALUE **vals)
case V_COM:
tmp1.v_type = V_COM;
tmp1.v_com = c_sinh(vals[0]->v_com, err);
if (tmp1.v_com == NULL) {
return error_value(E_TANH3);
}
tmp2.v_type = V_COM;
tmp2.v_com = c_cosh(vals[0]->v_com, err);
if (tmp2.v_com == NULL) {
comfree(tmp1.v_com);
return error_value(E_TANH4);
}
divvalue(&tmp1, &tmp2, &result);
comfree(tmp1.v_com);
comfree(tmp2.v_com);
@@ -2517,8 +2547,15 @@ f_coth(int count, VALUE **vals)
case V_COM:
tmp1.v_type = V_COM;
tmp1.v_com = c_cosh(vals[0]->v_com, err);
if (tmp1.v_com == NULL) {
return error_value(E_COTH3);
}
tmp2.v_type = V_COM;
tmp2.v_com = c_sinh(vals[0]->v_com, err);
if (tmp2.v_com == NULL) {
comfree(tmp1.v_com);
return error_value(E_COTH4);
}
divvalue(&tmp1, &tmp2, &result);
comfree(tmp1.v_com);
comfree(tmp2.v_com);
@@ -2555,6 +2592,9 @@ f_sech(int count, VALUE **vals)
case V_COM:
tmp.v_type = V_COM;
tmp.v_com = c_cosh(vals[0]->v_com, err);
if (tmp.v_com == NULL) {
return error_value(E_SECH3);
}
invertvalue(&tmp, &result);
comfree(tmp.v_com);
break;
@@ -2592,6 +2632,9 @@ f_csch(int count, VALUE **vals)
case V_COM:
tmp.v_type = V_COM;
tmp.v_com = c_sinh(vals[0]->v_com, err);
if (tmp.v_com == NULL) {
return error_value(E_CSCH3);
}
invertvalue(&tmp, &result);
comfree(tmp.v_com);
break;
@@ -2626,7 +2669,7 @@ f_atan(int count, VALUE **vals)
case V_COM:
tmp = c_atan(vals[0]->v_com, err);
if (tmp == NULL)
return error_value(E_LOGINF);
return error_value(E_ATAN3);
result.v_type = V_COM;
result.v_com = tmp;
if (cisreal(tmp)) {
@@ -2666,7 +2709,7 @@ f_acot(int count, VALUE **vals)
case V_COM:
tmp = c_acot(vals[0]->v_com, err);
if (tmp == NULL)
return error_value(E_LOGINF);
return error_value(E_ACOT3);
result.v_type = V_COM;
result.v_com = tmp;
if (cisreal(tmp)) {
@@ -2718,6 +2761,9 @@ f_asin(int count, VALUE **vals)
default:
return error_value(E_ASIN2);
}
if (result.v_com == NULL) {
return error_value(E_ASIN3);
}
if (result.v_type == V_COM && cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -2764,6 +2810,9 @@ f_acos(int count, VALUE **vals)
default:
return error_value(E_ACOS2);
}
if (result.v_com == NULL) {
return error_value(E_ACOS3);
}
if (result.v_type == V_COM && cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -2794,7 +2843,7 @@ f_asec(int count, VALUE **vals)
switch (vals[0]->v_type) {
case V_NUM:
if (qiszero(vals[0]->v_num))
return error_value(E_LOGINF);
return error_value(E_ASEC3);
result.v_num = qasec(vals[0]->v_num, err);
result.v_type = V_NUM;
if (result.v_num == NULL) {
@@ -2813,9 +2862,10 @@ f_asec(int count, VALUE **vals)
default:
return error_value(E_ASEC2);
}
if (result.v_com == NULL) {
return error_value(E_ASEC3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -2847,7 +2897,7 @@ f_acsc(int count, VALUE **vals)
switch (vals[0]->v_type) {
case V_NUM:
if (qiszero(vals[0]->v_num))
return error_value(E_LOGINF);
return error_value(E_ACSC3);
result.v_num = qacsc(vals[0]->v_num, err);
result.v_type = V_NUM;
if (result.v_num == NULL) {
@@ -2866,9 +2916,10 @@ f_acsc(int count, VALUE **vals)
default:
return error_value(E_ACSC2);
}
if (result.v_com == NULL) {
return error_value(E_ACSC3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -2903,6 +2954,9 @@ f_asinh(int count, VALUE **vals)
break;
case V_COM:
tmp = c_asinh(vals[0]->v_com, err);
if (tmp == NULL) {
return error_value(E_ASINH3);
}
result.v_type = V_COM;
result.v_com = tmp;
if (cisreal(tmp)) {
@@ -2955,6 +3009,9 @@ f_acosh(int count, VALUE **vals)
default:
return error_value(E_ACOSH2);
}
if (result.v_com == NULL) {
return error_value(E_ACOSH3);
}
if (result.v_type == V_COM && cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -3002,9 +3059,10 @@ f_atanh(int count, VALUE **vals)
default:
return error_value(E_ATANH2);
}
if (result.v_com == NULL) {
return error_value(E_ATANH3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -3053,9 +3111,10 @@ f_acoth(int count, VALUE **vals)
default:
return error_value(E_ACOTH2);
}
if (result.v_com == NULL) {
return error_value(E_ACOTH3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -3087,7 +3146,7 @@ f_asech(int count, VALUE **vals)
switch (vals[0]->v_type) {
case V_NUM:
if (qiszero(vals[0]->v_num))
return error_value(E_LOGINF);
return error_value(E_ASECH3);
result.v_num = qasech(vals[0]->v_num, err);
result.v_type = V_NUM;
if (result.v_num == NULL) {
@@ -3106,9 +3165,10 @@ f_asech(int count, VALUE **vals)
default:
return error_value(E_ASECH2);
}
if (result.v_com == NULL) {
return error_value(E_ASECH3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -3140,7 +3200,7 @@ f_acsch(int count, VALUE **vals)
switch (vals[0]->v_type) {
case V_NUM:
if (qiszero(vals[0]->v_num))
return error_value(E_LOGINF);
return error_value(E_ACSCH3);
result.v_num = qacsch(vals[0]->v_num, err);
result.v_type = V_NUM;
if (result.v_num == NULL) {
@@ -3159,9 +3219,10 @@ f_acsch(int count, VALUE **vals)
default:
return error_value(E_ACSCH2);
}
if (result.v_com == NULL) {
return error_value(E_ACSCH3);
}
if (result.v_type == V_COM) {
if (result.v_com == NULL)
return error_value(E_LOGINF);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -3260,7 +3321,7 @@ f_agd(int count, VALUE **vals)
return error_value(E_AGD2);
}
if (result.v_com == NULL)
return error_value(E_AGD3);
return error_value(E_AGD3);
if (cisreal(result.v_com)) {
q = qlink(result.v_com->real);
comfree(result.v_com);
@@ -6022,12 +6083,15 @@ f_strerror(int count, VALUE **vals)
/* firewall - return generic error string if it is not assigned */
if (i >= nexterrnum || (i > E__HIGHEST && i < E_USERDEF)
|| (i < E__BASE && strerror(i) == NULL)) {
cp = (char *) malloc(sizeof("Error 1234567890")+1);
size_t snprintf_len; /* malloced snprintf buffer length */
snprintf_len = sizeof("Unknown error 12345678901234567890")+1;
cp = (char *) malloc(snprintf_len+1);
if (cp == NULL) {
math_error("Out of memory for strerror");
/*NOTREACHED*/
}
sprintf(cp, "Unknown error %ld", i);
snprintf(cp, snprintf_len, "Unknown error %ld", i);
cp[snprintf_len] = '\0'; /* paranoia */
result.v_str = makestring(cp);
return result;
}
@@ -7550,6 +7614,8 @@ f_putenv(int count, VALUE **vals)
* parse args
*/
if (count == 2) {
size_t snprintf_len; /* malloced snprintf buffer length */
/* firewall */
if (vals[0]->v_type != V_STR || vals[1]->v_type != V_STR) {
math_error("Non-string argument for putenv");
@@ -7557,14 +7623,17 @@ f_putenv(int count, VALUE **vals)
}
/* convert putenv("foo","bar") into putenv("foo=bar") */
putenv_str = (char *)malloc(vals[0]->v_str->s_len + 1 +
vals[1]->v_str->s_len + 1);
snprintf_len = vals[0]->v_str->s_len + 1 +
vals[1]->v_str->s_len + 1;
putenv_str = (char *)malloc(snprintf_len+1);
if (putenv_str == NULL) {
math_error("Cannot allocate string in putenv");
/*NOTREACHED*/
}
sprintf(putenv_str, "%s=%s", vals[0]->v_str->s_str,
snprintf(putenv_str, snprintf_len,
"%s=%s", vals[0]->v_str->s_str,
vals[1]->v_str->s_str);
putenv_str[snprintf_len] = '\0'; /* paranoia */
} else {

View File

@@ -1,7 +1,7 @@
/*
* have_stdvs - try <stdarg.h> to see if it really works with vsprintf()
* have_stdvs - try <stdarg.h> to see if it really works with vsnprintf()
*
* Copyright (C) 1999,2014 Landon Curt Noll
* Copyright (C) 1999,2014,2018 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
@@ -25,16 +25,16 @@
*/
/*
* On some systems that have both <stdarg.h> and <varargs.h>, vsprintf()
* On some systems that have both <stdarg.h> and <varargs.h>, vsnprintf()
* does not work well under one type of include file.
*
* Some systems (such as UMIPS) have bugs in the <stdarg.h> implementation
* that show up in vsprintf(), so we may have to try to use sprintf()
* as if it were vsprintf() and hope for the best.
* that show up in vsnprintf(), so we may have to try to use snprintf()
* as if it were vsnprintf() and hope for the best.
*
* This program will output #defines and exits 0 if vsprintf() (or sprintf())
* produces the results that we expect. This program exits 1 if vsprintf()
* (or sprintf()) produces unexpected results while using the <stdarg.h>
* This program will output #defines and exits 0 if vsnprintf() (or snprintf())
* produces the results that we expect. This program exits 1 if vsnprintf()
* (or snprintf()) produces unexpected results while using the <stdarg.h>
* include file.
*/
@@ -57,39 +57,24 @@
# include <stdlib.h>
#endif
#undef VSPRINTF_SIZE_T
#undef VSNPRINTF_SIZE_T
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || \
defined(__cplusplus)
# define VSPRINTF_SIZE_T size_t
# define VSNPRINTF_SIZE_T size_t
#else
# define VSPRINTF_SIZE_T long
# define VSNPRINTF_SIZE_T long
#endif
char buf[BUFSIZ];
char buf[BUFSIZ+1];
void
try_this(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
#if !defined(DONT_HAVE_VSPRINTF)
vsprintf(buf, fmt, ap);
#else
sprintf(buf, fmt, ap);
#endif
va_end(ap);
}
void
try_nthis(char *fmt, VSPRINTF_SIZE_T size, ...)
try_nthis(char *fmt, VSNPRINTF_SIZE_T size, ...)
{
va_list ap;
va_start(ap, size);
#if !defined(DONT_HAVE_VSPRINTF)
#if !defined(DONT_HAVE_VSNPRINTF)
vsnprintf(buf, size, fmt, ap);
#else
snprintf(buf, size, fmt, ap);
@@ -106,36 +91,12 @@ main(void)
*/
buf[0] = '\0';
/*
* test variable args and vsprintf/sprintf
*/
try_this("@%d:%s:%d@", 1, "hi", 2);
if (strcmp(buf, "@1:hi:2@") != 0) {
#if !defined(DONT_HAVE_VSPRINTF)
/* <stdarg.h> with vsprintf() didn't work */
#else
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
#endif
exit(1);
}
try_this("%s %d%s%d%d %s",
"Landon Noll 1st coproved that", 2, "^", 21701, -1, "was prime");
if (strcmp(buf,
"Landon Noll 1st coproved that 2^21701-1 was prime") != 0) {
#if !defined(DONT_HAVE_VSPRINTF)
/* <stdarg.h> with vsprintf() didn't work */
#else
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
#endif
exit(1);
}
/*
* test variable args and vsnprintf/snprintf
*/
try_nthis("@%d:%s:%d@", sizeof(buf)-1, 1, "hello", 5);
if (strcmp(buf, "@1:hello:5@") != 0) {
#if !defined(DONT_HAVE_VSPRINTF)
#if !defined(DONT_HAVE_VSNPRINTF)
/* <stdarg.h> with vsnprintf() didn't work */
#else
/* <stdarg.h> with snprintf() simulating vsnprintf() didn't work */
@@ -146,7 +107,7 @@ main(void)
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
if (strcmp(buf,
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
#if !defined(DONT_HAVE_VSPRINTF)
#if !defined(DONT_HAVE_VSNPRINTF)
/* <stdarg.h> with vsnprintf() didn't work */
#else
/* <stdarg.h> with snprintf() simulating vsnprintf() didn't work */
@@ -158,7 +119,7 @@ main(void)
* report the result
*/
puts("/* what type of variable args do we have? */");
#if defined(DONT_HAVE_VSPRINTF)
#if defined(DONT_HAVE_VSNPRINTF)
puts("/*");
puts(" * SIMULATE_STDARG");
puts(" *");
@@ -179,22 +140,21 @@ main(void)
puts("#define STDARG /* use <stdarg.h> */");
puts("#include <stdarg.h>");
#endif
puts("\n/* should we use vsprintf() and vsnprintf()? */");
#if !defined(DONT_HAVE_VSPRINTF)
puts("#define HAVE_VSPRINTF /* yes */");
puts("\n/* should we use vsnprintf() and vsnprintf()? */");
#if !defined(DONT_HAVE_VSNPRINTF)
puts("#define HAVE_VSNPRINTF /* yes */");
#else
puts("/*");
puts(" * Hack aleart!!!");
puts(" *");
puts(" * Systems that do not have vsprintf() need something. In some");
puts(" * cases the sprintf function will deal correctly with the");
puts(" * va_alist 3rd arg. Same gors for a lack of an vsnprintf()");
puts(" * Systems that do not have vsnprintf() need something. In some");
puts(" * cases the snprintf function will deal correctly with the");
puts(" * va_alist 4th arg. Same gors for a lack of an vsnprintf()");
puts(" * function. In either case we use the #defines below and");
puts(" * hope for the best!");
puts(" */");
puts("#define vsprintf sprintf");
puts("#define vsnprintf snprintf");
puts("#undef HAVE_VSPRINTF");
puts("#undef HAVE_VSNPRINTF");
#endif
/* exit(0); */
return 0;

View File

@@ -1,7 +1,7 @@
/*
* have_varvs - try <varargs.h> to see if it really works with vsprintf()
* have_varvs - try <varargs.h> to see if it really works with vsnprintf()
*
* Copyright (C) 1999 Landon Curt Noll
* Copyright (C) 1999,2018 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
@@ -26,12 +26,12 @@
/*
* Some systems have bugs in the <varargs.h> implementation that show up in
* vsprintf(), so we may have to try to use sprintf() as if it were vsprintf()
* and hope for the best.
* vsnprintf(), so we may have to try to use snprintf() as if it were
* vsnprintf() and hope for the best.
*
* This program will output #defines and exits 0 if vsprintf() (or sprintf())
* produces the results that we expect. This program exits 1 if vsprintf()
* (or sprintf()) produces unexpected results while using the <stdarg.h>
* This program will output #defines and exits 0 if vsnprintf() (or snprintf())
* produces the results that we expect. This program exits 1 if vsnprintf()
* (or snprintf()) produces unexpected results while using the <stdarg.h>
* include file.
*/
@@ -48,43 +48,27 @@
# include <string.h>
#endif
#undef VSPRINTF_SIZE_T
#undef VSNPRINTF_SIZE_T
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || \
defined(__cplusplus)
# define VSPRINTF_SIZE_T size_t
# define VSNPRINTF_SIZE_T size_t
#else
# define VSPRINTF_SIZE_T long
# define VSNPRINTF_SIZE_T long
#endif
char buf[BUFSIZ];
char buf[BUFSIZ+1];
#if !defined(STDARG) && !defined(SIMULATE_STDARG)
#include <varargs.h>
void
try_this(char *fmt, ...)
try_nthis(char *fmt, VSNPRINTF_SIZE_T size, ...)
{
va_list ap;
va_start(ap);
#if !defined(DONT_HAVE_VSPRINTF)
vsprintf(buf, fmt, ap);
#else
sprintf(buf, fmt, ap);
#endif
va_end(ap);
}
void
try_nthis(char *fmt, VSPRINTF_SIZE_T size, ...)
{
va_list ap;
va_start(ap);
#if !defined(DONT_HAVE_VSPRINTF)
#if !defined(DONT_HAVE_VSNPRINTF)
vsnprintf(buf, size, fmt, ap);
#else
snprintf(buf, size, fmt, ap);
@@ -96,13 +80,7 @@ try_nthis(char *fmt, VSPRINTF_SIZE_T size, ...)
#else
void
try_this(char *a, int b, char *c, int d)
{
return;
}
void
try_nthis(char *a, VSPRINTF_SIZE_T size, int b, char *c, int d)
try_nthis(char *a, VSNPRINTF_SIZE_T size, int b, char *c, int d)
{
return;
}
@@ -118,36 +96,12 @@ main(void)
*/
buf[0] = '\0';
/*
* test variable args and vsprintf/sprintf
*/
try_this("@%d:%s:%d@", 1, "hi", 2);
if (strcmp(buf, "@1:hi:2@") != 0) {
#if !defined(DONT_HAVE_VSPRINTF)
/* <varargs.h> with vsprintf() didn't work */
#else
/* <varargs.h> with sprintf() simulating vsprintf() didn't work */
#endif
exit(1);
}
try_this("%s %d%s%d%d %s",
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
if (strcmp(buf,
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
#if !defined(DONT_HAVE_VSPRINTF)
/* <varargs.h> with vsprintf() didn't work */
#else
/* <varargs.h> with sprintf() simulating vsprintf() didn't work */
#endif
exit(1);
}
/*
* test variable args and vsnprintf/snprintf
*/
try_nthis("@%d:%s:%d@", sizeof(buf)-1, 1, "hello", 5);
if (strcmp(buf, "@1:hello:5@") != 0) {
#if !defined(DONT_HAVE_VSPRINTF)
#if !defined(DONT_HAVE_VSNPRINTF)
/* <varargs.h> with vsnprintf() didn't work */
#else
/* <varargs.h> with snprintf() simulating vsnprintf() didn't work */
@@ -158,7 +112,7 @@ main(void)
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
if (strcmp(buf,
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
#if !defined(DONT_HAVE_VSPRINTF)
#if !defined(DONT_HAVE_VSNPRINTF)
/* <varargs.h> with vsnprintf() didn't work */
#else
/* <varargs.h> with snprintf() simulating vsnprintf() didn't work */
@@ -172,22 +126,21 @@ main(void)
puts("/* what type of variable args do we have? */");
puts("#define VARARGS /* use <varargs.h> */");
puts("#include <varargs.h>");
puts("\n/* should we use vsprintf() and vsnprintf()? */");
#if !defined(DONT_HAVE_VSPRINTF)
puts("#define HAVE_VSPRINTF /* yes */");
puts("\n/* should we use vsnprintf() and vsnprintf()? */");
#if !defined(DONT_HAVE_VSNPRINTF)
puts("#define HAVE_VSNPRINTF /* yes */");
#else
puts("/*");
puts(" * Hack aleart!!!");
puts(" *");
puts(" * Systems that do not have vsprintf() need something. In some");
puts(" * cases the sprintf function will deal correctly with the");
puts(" * va_alist 3rd arg. Same gors for a lack of an vsnprintf()");
puts(" * Systems that do not have vsnprintf() need something. In some");
puts(" * cases the snprintf() function will deal correctly with the");
puts(" * va_alist 4th arg. Same gors for a lack of an vsnprintf()");
puts(" * function. In either case we use the #defines below and");
puts(" * hope for the best!");
puts(" */");
puts("#define vsprintf sprintf");
puts("#define vsnprintf snprintf");
puts("#undef HAVE_VSPRINTF");
puts("#undef HAVE_VSNPRINTF");
#endif
/* exit(0); */
return 0;

17
help.c
View File

@@ -1,7 +1,7 @@
/*
* help - display help for calc
*
* Copyright (C) 1999-2007,2014 Landon Curt Noll
* Copyright (C) 1999-2007,2014,2018 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
@@ -183,6 +183,7 @@ givehelp(char *type)
FILE *stream; /* help file stream */
char *helppath; /* path to the help file */
char *c;
size_t snprintf_len; /* malloced snprintf buffer length */
/*
* check permissions to see if we are allowed to help
@@ -247,18 +248,21 @@ givehelp(char *type)
*/
#if defined(CUSTOM)
if (sizeof(CUSTOMHELPDIR) > sizeof(HELPDIR)) {
helppath = (char *)malloc(sizeof(CUSTOMHELPDIR)+1+strlen(type));
snprintf_len = sizeof(CUSTOMHELPDIR)+1+strlen(type) + 1;
} else {
helppath = (char *)malloc(sizeof(HELPDIR)+1+strlen(type));
snprintf_len = sizeof(HELPDIR)+1+strlen(type) + 1;
}
helppath = (char *)malloc(snprintf_len+1);
#else /* CUSTOM */
helppath = (char *)malloc(sizeof(HELPDIR)+1+strlen(type));
snprintf_len = sizeof(HELPDIR)+1+strlen(type) + 1;
helppath = (char *)malloc(snprintf_len+1);
#endif /* CUSTOM */
if (helppath == NULL) {
fprintf(stderr, "malloc failure in givehelp()\n");
return;
}
sprintf(helppath, "%s/%s", HELPDIR, type);
snprintf(helppath, snprintf_len, "%s/%s", HELPDIR, type);
helppath[snprintf_len] = '\0'; /* paranoia */
stream = fopen(helppath, "r");
if (stream != NULL) {
@@ -274,7 +278,8 @@ givehelp(char *type)
*/
} else {
sprintf(helppath, "%s/%s", CUSTOMHELPDIR, type);
snprintf(helppath, snprintf_len, "%s/%s", CUSTOMHELPDIR, type);
helppath[snprintf_len] = '\0'; /* paranoia */
stream = fopen(helppath, "r");
if (stream == NULL) {

View File

@@ -88,6 +88,31 @@ Command sequence
If the -m mode disallows opening of files for reading,
this command will be disabled.
To read a calc resource file without printing various
messages about defined functions, the "resource_debug"
config should be set to zero. For example:
read lucas;
will, by default, print messages such as:
lucas(h,n) defined
gen_u2(h,n,v1) defined
gen_u0(h,n,v1) defined
rodseth_xhn(x,h,n) defined
gen_v1(h,n) defined
ldebug(funct,str) defined
legacy_gen_v1(h,n) defined
When "resource_debug" is zero, such messages are silenced.
config("resource_debug", 0),;
read lucas;
To silence such messages on the calc command line, try:
calc -p -D :0 'read -once lucas; lucas(1, 23209);'
write calc commands
-------------------
@@ -350,7 +375,7 @@ Command sequence
statement flow control and declaration statements
usage how to invoke the calc command and calc -options
## Copyright (C) 1999-2006 Landon Curt Noll
## Copyright (C) 1999-2006,2018 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

View File

@@ -949,6 +949,48 @@ EXAMPLE
; display()
50
; /*
* NOTE: When displaying many digits after the decimal point
* be sure to set display(digits) (see 'help display') to
* large enough AND to set epsilon(eps) (see 'help epsilon')
* small enough (or if the function has a esp argument,
* give a eps argument that is small enough) to display
* the value correctly.
*/
; config("tilde", 1),;
; /* NOTE: display has too few digits and epsilon is not small enough */
; config("display", 12),; /* or display(12),; */
; printf("%f\n", pi(1e-10));
3.1415926536
; config("epsilon", 1e-10),; /* or epsilon(1e-10),; */
; printf("%f\n", pi());
3.1415926536
; /* NOTE: display has too few digits yet epsilon is small enough */
; config("display", 12),; /* or display(12),; */
; printf("%f\n", pi(1e-72));
~3.141592653590
; config("epsilon", 1e-72),; /* or epsilon(1e-72),; */
; printf("%f\n", pi());
~3.141592653590
; /* NOTE: display has enough digits but epsilon is not small enough */
; config("display", 72),; /* or display(72),; */
; printf("%f\n", pi(1e-10));
3.1415926536
; config("epsilon", 1e-10),; /* or epsilon(1e-10),; */
; printf("%f\n", pi());
3.1415926536
/* NOTE: display has enough digits and epsilon is small enough */
; config("display", 72),; /* or display(72),; */
; printf("%f\n", pi(1e-72));
3.141592653589793238462643383279502884197169399375105820974944592307816406
; config("epsilon", 1e-72),; /* or epsilon(1e-72),; */
; printf("%f\n", pi());
3.141592653589793238462643383279502884197169399375105820974944592307816406
LIMITS
none
@@ -956,9 +998,9 @@ LINK LIBRARY
n/a
SEE ALSO
usage, custom, custom_cal, usage, epsilon, display
custom, custom_cal, display, epsilon, fprintf, printf, strprintf, usage
## Copyright (C) 1999-2007 Landon Curt Noll
## Copyright (C) 1999-2007,2018 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

View File

@@ -45,6 +45,48 @@ EXAMPLE
; print display(5), 2/3
40 ~0.66667
; /*
* NOTE: When displaying many digits after the decimal point
* be sure to set display(digits) (see 'help display') to
* large enough AND to set epsilon(eps) (see 'help epsilon')
* small enough (or if the function has a esp argument,
* give a eps argument that is small enough) to display
* the value correctly.
*/
; config("tilde", 1),;
; /* NOTE: display has too few digits and epsilon is not small enough */
; display(12),;
; printf("%f\n", pi(1e-10));
3.1415926536
; epsilon(1e-10),;
; printf("%f\n", pi());
3.1415926536
; /* NOTE: display has too few digits yet epsilon is small enough */
; display(12),;
; printf("%f\n", pi(1e-72));
~3.141592653590
; epsilon(1e-72),;
; printf("%f\n", pi());
~3.141592653590
; /* NOTE: display has enough digits but epsilon is not small enough */
; display(72),;
; printf("%f\n", pi(1e-10));
3.1415926536
; epsilon(1e-10),;
; printf("%f\n", pi());
3.1415926536
/* NOTE: display has enough digits and epsilon is small enough */
; display(72),;
; printf("%f\n", pi(1e-72));
3.141592653589793238462643383279502884197169399375105820974944592307816406
; epsilon(1e-72),;
; printf("%f\n", pi());
3.141592653589793238462643383279502884197169399375105820974944592307816406
LIMITS
d >= 0
@@ -52,9 +94,9 @@ LINK LIBRARY
none
SEE ALSO
config
config, epsilon, fprintf, printf, strprintf
## Copyright (C) 2004 Landon Curt Noll
## Copyright (C) 2004,2018 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

View File

@@ -16,13 +16,57 @@ DESCRIPTION
and sets the stored epsilon value to eps.
The stored epsilon value is used as default value for eps in
the functions appr(x, eps, rnd), sqrt(x, eps, rnd), etc.
many functions such as appr(x, eps, rnd), sqrt(x, eps, rnd),
pi(eps), sin(x, eps), tanh(x, eps), etc.
EXAMPLE
; epsilon(1e-20),;
; oldeps = epsilon(1e-6)
; print epsilon(), sqrt(2), epsilon(1e-4), sqrt(2), epsilon(oldeps)
; .000001 1.414214 .000001 1.4142 .0001
; /*
* NOTE: When displaying many digits after the decimal point
* be sure to set display(digits) (see 'help display') to
* large enough AND to set epsilon(eps) (see 'help epsilon')
* small enough (or if the function has a esp argument,
* give a eps argument that is small enough) to display
* the value correctly.
*/
; config("tilde", 1),;
; /* NOTE: display has too few digits and epsilon is not small enough */
; display(12),;
; printf("%f\n", pi(1e-10));
3.1415926536
; epsilon(1e-10),;
; printf("%f\n", pi());
3.1415926536
; /* NOTE: display has too few digits yet epsilon is small enough */
; display(12),;
; printf("%f\n", pi(1e-72));
~3.141592653590
; epsilon(1e-72),;
; printf("%f\n", pi());
~3.141592653590
; /* NOTE: display has enough digits but epsilon is not small enough */
; display(72),;
; printf("%f\n", pi(1e-10));
3.1415926536
; epsilon(1e-10),;
; printf("%f\n", pi());
3.1415926536
/* NOTE: display has enough digits and epsilon is small enough */
; display(72),;
; printf("%f\n", pi(1e-72));
3.141592653589793238462643383279502884197169399375105820974944592307816406
; epsilon(1e-72),;
; printf("%f\n", pi());
3.141592653589793238462643383279502884197169399375105820974944592307816406
LIMITS
none
@@ -31,9 +75,9 @@ LINK LIBRARY
NUMBER *_epsilon_
SEE ALSO
config
config, display, fprintf, printf, strprintf
## Copyright (C) 1999 Landon Curt Noll
## Copyright (C) 1999,2018 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

View File

@@ -45,6 +45,48 @@ EXAMPLE
[2] = "undefined"
[3] = NULL
; /*
* NOTE: When displaying many digits after the decimal point
* be sure to set display(digits) (see 'help display') to
* large enough AND to set epsilon(eps) (see 'help epsilon')
* small enough (or if the function has a esp argument,
* give a eps argument that is small enough) to display
* the value correctly.
*/
; config("tilde", 1),;
; /* NOTE: display has too few digits and epsilon is not small enough */
; display(12),;
; fprintf(files(1), "%f\n", pi(1e-10));
3.1415926536
; epsilon(1e-10),;
; fprintf(files(1), "%f\n", pi());
3.1415926536
; /* NOTE: display has too few digits yet epsilon is small enough */
; display(12),;
; fprintf(files(1), "%f\n", pi(1e-72));
~3.141592653590
; epsilon(1e-72),;
; fprintf(files(1), "%f\n", pi());
~3.141592653590
; /* NOTE: display has enough digits but epsilon is not small enough */
; display(72),;
; fprintf(files(1), "%f\n", pi(1e-10));
3.1415926536
; epsilon(1e-10),;
; fprintf(files(1), "%f\n", pi());
3.1415926536
/* NOTE: display has enough digits and epsilon is small enough */
; display(72),;
; fprintf(files(1), "%f\n", pi(1e-72));
3.141592653589793238462643383279502884197169399375105820974944592307816406
; epsilon(1e-72),;
; fprintf(files(1), "%f\n", pi());
3.141592653589793238462643383279502884197169399375105820974944592307816406
LIMITS
The number of arguments of fprintf() is not to exceed 1024.
@@ -52,9 +94,9 @@ LINK LIBRARY
none
SEE ALSO
printf, strprintf, print
config, display, epsilon, printf, strprintf
## Copyright (C) 1999-2006 Landon Curt Noll
## Copyright (C) 1999-2006,2018 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

View File

@@ -54,13 +54,13 @@ DESCRIPTION
The elements of the matrix are stored internally as a linear array
in which locations are arranged in order of increasing indices.
For example, in order of location, the six element of A = mat [2,3]
are
are:
A[0,0], A[0,1], A[0,2], A[1,0], A[1,,1], A[1,2].
A[0,0], A[0,1], A[0,2], A[1,0], A[1,1], and A[1,2].
These elements may also be specified using the double-bracket operator
with a single integer index as in A[[0]], A[[1]], ..., A[[5]].
If p is assigned the value &A[0.0], the address of A[[i]] for 0 <= i < 6
If p is assigned the value &A[0,0], the address of A[[i]] for 0 <= i < 6
is p + i as long as A exists and a new value is not assigned to A.
When a matrix is created, each element is initially assigned the
@@ -414,7 +414,7 @@ SEE ALSO
det, inverse, isident, test, config, search, rsearch, reverse, copy,
blkcpy, dp, cp, randperm, sort
## Copyright (C) 1999-2006 Landon Curt Noll
## Copyright (C) 1999-2006,2018 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

View File

@@ -28,7 +28,7 @@ DESCRIPTION
zero or more decimal digits
an optional '. followed by zero or more decimal deigits
an optional 'l'
one of the letters: d, s, c, f, e, r, o, x, b,
one of the letters: d, s, c, f, e, g, r, o, x, b,
If any other character is read, the '%' and any characters
between '%' and the character are ignored and no specifier is
@@ -51,26 +51,39 @@ DESCRIPTION
d, s, c current config("mode")
f real (decimal, floating point)
e exponential
g general format (real or exponential)
r fractional
o octal
x hexadecimal
b binary
If the number of arguments after fmt is less than the
number of format specifiers in fmt, the "missing" arguments
may be taken to be null values - these contribute nothing to the
output; if a positive width w has been specified, the effect is
to produce w spaces, e.g. printf("abc%6dxyz") prints "abc xyz".
If the number of arguments after fmt is less than the number
of format specifiers in fmt, the "missing" arguments may be
taken to be null values - these contribute nothing to the output;
if a positive width w has been specified, the effect is to
produce w spaces, e.g., printf("abc%6dxyz") prints "abc xyz".
If i <= the number of specifiers in fmt, the value of argument x_i
is printed in the format specified by the i-th specifier.
If a positive width w has been specified and normal printing of x_i
does not include a '\n' character, what is printed will if necessary
be padded with spaces so that the length of the printed output
is at least the w. Note that control
characters like '\t', '\b' each count as one character. If
the 'right-pad' flag has been set, the padding is on the right;
otherwise it is on the left.
Control charters may be given in fmt by escaping them with
the \ character. The following control charter escape
sequences are recognized:
\a audible bell byte 0x07 in ASCII encoding
\b backspace byte 0x08 in ASCII encoding
\f form feed byte 0x0c in ASCII encoding
\n newline byte 0x0b in ASCII encoding
\r return byte 0x0a in ASCII encoding
\t tab byte 0x0d in ASCII encoding
\v vertical tab byte 0x09 in ASCII encoding
If i <= the number of specifiers in fmt, the value of argument
x_i is printed in the format specified by the i-th specifier.
If a positive width w has been specified and normal printing
of x_i does not include a '\n' character, what is printed will
if necessary be padded with spaces so that the length of the
printed output is at least the w. Note that control characters
(e.g., '\a', '\b', '\f', '\n', '\r', '\t', '\n') count as one
character. If the 'right-pad' flag has been set, the padding
is on the right; otherwise it is on the left.
If i > the number of specifiers in fmt, the value of argument x_i
does not contribute to the printing. However, as all arguments
@@ -83,22 +96,38 @@ DESCRIPTION
specified precision will be ignored except for floating-point
mode.
In the case of floating-point (f) format the precision determines
the maximum number of decimal places to be
displayed. Other aspects of this printing may be affected by the
configuration parameters "outround", "tilde", "fullzero", "leadzero".
The (g) general format will print the as real (f) (decimal or
floating point) or as an exponential (e) depending on the
configuration parameter "display".
In the case of floating-point (f) format, and the (g) general
format, the precision determines the maximum number of decimal
places to be displayed. Other aspects of this printing may be
affected by the configuration parameters "outround", "tilde",
"fullzero", "leadzero".
EXAMPLE
; c = config("epsilon", 1e-6); c = config("display", 6);
; c = config("tilde", 1); c = config("outround", 0);
; c = config("fullzero", 0);
; config("epsilon", 1e-6),;
: config("display", 6),;
; config("tilde", 1),;
; config("outround", 0),;
; config("fullzero", 0),;
; fmt = "%f,%10f,%-10f,%10.4f,%.4f,%.f.\n";
; a = sqrt(3);
; printf(fmt,a,a,a,a,a,a);
1.732051, 1.732051,1.732051 , ~1.7320,~1.7320,~1.
; c = config("tilde", 0); c = config("outround",24);
; c = config("fullzero", 1);
; config("display", 5),;
: config("tilde", 0),;
; printf("%f\n", pi());
3.1416
; config("display", 10),;
; printf("%f\n", pi());
3.141592654
; config("tilde", 0),;
: config("outround",24),;
; config("fullzero", 1),;
; printf(fmt,a,a,a,a,a,a);
1.732051, 1.732051,1.732051 , 1.7321,1.7321,2.
@@ -116,6 +145,82 @@ EXAMPLE
[2] = "undefined"
[3] = NULL
; config("display", 50),;
; printf("%g %g\n%g %g\n", 1e5, 1e49, 1e50, 1e500);
100000 100000000000000000000000000000000000000000000000000
1e50 1e500
; config("display", 10),;
: config("tilde", 0),;
; printf("%f %f %f\n%f %f %f\n",
exp(1), exp(2), exp(3), exp(4), exp(5), exp(6));
2.7182818285 7.3890560989 20.0855369232
54.5981500331 148.4131591026 403.4287934927
; printf("%e %e %e\n%e %e %e\n",
exp(1), exp(2), exp(3), exp(4), exp(5), exp(6));
2.7182818285 7.3890560989 2.0085536923e1
5.4598150033e1 1.4841315910e2 4.0342879349e2
; printf("%g %g %g\n%g %g %g\n",
exp(1), exp(2), exp(3), exp(4), exp(5), exp(6));
2.718281828 7.389056099 20.08553692
54.59815003 148.4131591 403.4287935
; config("display", 10),;
; config("tilde", 0),;
; printf("%f %f %f\n%f %f %f\n",
exp(20), exp(21), exp(22), exp(23), exp(24), exp(25));
485165195.4097902780 1318815734.4832146972 3584912846.1315915617
9744803446.2489026000 26489122129.8434722941 72004899337.3858725242`
; printf("%e %e %e\n%e %e %e\n",
exp(20), exp(21), exp(22), exp(23), exp(24), exp(25));
4.8516519541e8 1.3188157345e9 3.5849128461e9
9.7448034462e9 2.6489122130e10 7.2004899337e10
; printf("%g %g %g\n%g %g %g\n",
exp(20), exp(21), exp(22), exp(23), exp(24), exp(25));
485165195.4 1318815734 3584912846
9744803446 2.648912213e10 7.200489934e10
; /*
* NOTE: When displaying many digits after the decimal point
* be sure to set display(digits) (see 'help display') to
* large enough AND to set epsilon(eps) (see 'help epsilon')
* small enough (or if the function has a esp argument,
* give a eps argument that is small enough) to display
* the value correctly.
*/
; config("tilde", 1),;
; /* NOTE: display has too few digits and epsilon is not small enough */
; display(12),;
; printf("%f\n", pi(1e-10));
3.1415926536
; epsilon(1e-10),;
; printf("%f\n", pi());
3.1415926536
; /* NOTE: display has too few digits yet epsilon is small enough */
; display(12),;
; printf("%f\n", pi(1e-72));
~3.141592653590
; epsilon(1e-72),;
; printf("%f\n", pi());
~3.141592653590
; /* NOTE: display has enough digits but epsilon is not small enough */
; display(72),;
; printf("%f\n", pi(1e-10));
3.1415926536
; epsilon(1e-10),;
; printf("%f\n", pi());
3.1415926536
/* NOTE: display has enough digits and epsilon is small enough */
; display(72),;
; printf("%f\n", pi(1e-72));
3.141592653589793238462643383279502884197169399375105820974944592307816406
; epsilon(1e-72),;
; printf("%f\n", pi());
3.141592653589793238462643383279502884197169399375105820974944592307816406
LIMITS
The number of arguments of printf() is not to exceed 1024.
@@ -124,9 +229,9 @@ LINK LIBRARY
none
SEE ALSO
fprintf, strprintf, print
config, display, epsilon, fprintf, strprintf
## Copyright (C) 1999-2006 Landon Curt Noll
## Copyright (C) 1999-2006,2018 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

View File

@@ -1,5 +1,5 @@
NAME
randbit - additive 55 shuffle pseudo-random number generator
randbit - subtractive 100 shuffle pseudo-random number generator
SYNOPSIS
randbit([x])
@@ -42,7 +42,7 @@ LINK LIBRARY
SEE ALSO
seed, srand, randbit, isrand, random, srandom, israndom
## Copyright (C) 1999 Landon Curt Noll
## Copyright (C) 1999,2018 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

View File

@@ -18,14 +18,7 @@ DESCRIPTION
It should be pointed out that the information collected by seed
is almost certainly non-chaotic. This function is likely not
suitable for applications (such as cryptographic applications)
where the unpredictability of seeds is critical. For such critical
applications, LavaRnd should be used. See the URL:
http://www.LavaRnd.org/
for information about seeding a pseudo-random number generator
(such as rand() or random()) with the cryptographic hash of the
digitization of chaotic system.
where the unpredictability of seeds is critical.
Given the above warning, this builtin function produces a seed that is
suitable for most applications that desire a different pseudo-random
@@ -51,7 +44,7 @@ LINK LIBRARY
SEE ALSO
seed, srand, randbit, isrand, rand, random, srandom, israndom
## Copyright (C) 1999 Landon Curt Noll
## Copyright (C) 1999,2018 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

View File

@@ -332,13 +332,13 @@ LIMITS
iq >= 2^16
LINK LIBRARY
RAND *zsrandom(ZVALUE *pseed, MATRIX *pmat55)
RAND *zsetrandom(RAND *state)
RANDOM *zsrandom(ZVALUE *pseed, MATRIX *pmat55)
RANDOM *zsetrandom(RAND *state)
SEE ALSO
seed, srand, randbit, isrand, random, srandom, israndom
## Copyright (C) 1999 Landon Curt Noll
## Copyright (C) 1999,2018 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

View File

@@ -37,7 +37,7 @@ LIMITS
LINK LIBRARY
void math_divertio();
qprintnum(NUMBER *x, int outmode);
qprintnum(NUMBER *x, int outmode, LEN outdigits);
char *math_getdivertedio();
math_divertio();
@@ -47,7 +47,7 @@ LINK LIBRARY
SEE ALSO
base, base2, config
## Copyright (C) 1999-2006 Landon Curt Noll
## Copyright (C) 1999-2006,2018 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

View File

@@ -18,15 +18,68 @@ EXAMPLE
; strprintf("h=%d, i=%d", 2, 3);
"h=2, i=3"
; c = config("epsilon", 1e-6); c = config("display", 6);
; c = config("tilde", 1); c = config("outround", 0);
; c = config("fullzero", 0);
; config("epsilon", 1e-6),;
; config("display", 6),;
; config("tilde", 1),;
; config("outround", 0),;
; config("fullzero", 0),;
; fmt = "%f,%10f,%-10f,%10.4f,%.4f,%.f.\n";
; a = sqrt(3);
; strprintf(fmt,a,a,a,a,a,a);
"1.732051, 1.732051,1.732051 , ~1.7320,~1.7320,~1.
"
; config("display", 50),;
; fmt2 = "%g %g\n%g %g\n"
; strprintf(fmt2, 1e5, 1e49, 1e50, 1e500);
"100000 100000000000000000000000000000000000000000000000000
1e50 1e500
"
; /*
* NOTE: When displaying many digits after the decimal point
* be sure to set display(digits) (see 'help display') to
* large enough AND to set epsilon(eps) (see 'help epsilon')
* small enough (or if the function has a esp argument,
* give a eps argument that is small enough) to display
* the value correctly.
*/
; config("tilde", 1),;
; config("tab", 0),;
; fmt1 = "%f";
; /* NOTE: display has too few digits and epsilon is not small enough */
; display(12),;
; strprintf(fmt1, pi(1e-10));
"3.1415926536"
; epsilon(1e-10),;
; strprintf(fmt1, pi());
"3.1415926536"
; /* NOTE: display has too few digits yet epsilon is small enough */
; display(12),;
; strprintf(fmt1, pi(1e-72));
"~3.141592653590"
; epsilon(1e-72),;
; strprintf(fmt1, pi());
~3.141592653590
; /* NOTE: display has enough digits but epsilon is not small enough */
; display(72),;
; strprintf(fmt1, pi(1e-10));
"3.1415926536"
; epsilon(1e-10),;
; strprintf(fmt1, pi());
"3.1415926536"
/* NOTE: display has enough digits and epsilon is small enough */
; display(72),;
; strprintf(fmt1, pi(1e-72));
"3.141592653589793238462643383279502884197169399375105820974944592307816406"
; epsilon(1e-72),;
; strprintf(fmt1, pi());
"3.141592653589793238462643383279502884197169399375105820974944592307816406"
LIMITS
The number of arguments of strprintf() is not to exceed 1024.
@@ -34,12 +87,11 @@ LINK LIBRARY
none
SEE ALSO
strcat, strcpy, strerror, strlen, strncmp, strncpy, strpos,
strscan, strscanf, substr,
config, display, epsilon, fprintf, strcat, strcpy, strerror,
strlen, strncmp, strncpy, strpos, strscan, strscanf, substr,
printf
printf, fprintf, print
## Copyright (C) 1999-2006 Landon Curt Noll
## Copyright (C) 1999-2006,2018 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

View File

@@ -1,6 +1,6 @@
Builtin types
The calculator has the following built-in types.
The calculator has the following built-in types:
null value
This is the undefined value type. The function 'null'
@@ -101,7 +101,20 @@ Builtin types
using the result of the 'files' function. Such copies are
indistinguishable from each other.
## Copyright (C) 1999 Landon Curt Noll
The calculator also has a number of special types that as used
by some special builtin functions:
rand
A subtractive 100 shuffle pseudo-random number generator
state. This state is used by functions such as isrand()
and srand().
random
A Blum-Blum-Shub pseudo-random number generator state.
This state is used by functions such as israndom() and
srandom().
## Copyright (C) 1999,2018 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

2
hist.h
View File

@@ -36,7 +36,7 @@
#endif
#ifndef HIST_SIZE
#define HIST_SIZE (1024*10)
#define HIST_SIZE (1024*32)
#endif

15
input.c
View File

@@ -1,7 +1,7 @@
/*
* input - nested input source file reader
*
* Copyright (C) 1999-2007,2014 David I. Bell
* Copyright (C) 1999-2007,2014,2018 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,8 +59,8 @@ E_FUNC FILE *f_open(char *name, char *mode);
E_FUNC FILE *curstream(void);
#define TTYSIZE 100 /* reallocation size for terminal buffers */
#define MAXDEPTH 10 /* maximum depth of input */
#define TTYSIZE 8191 /* reallocation size for terminal buffers */
#define MAXDEPTH 255 /* maximum depth of input */
#define IS_READ 1 /* reading normally */
#define IS_REREAD 2 /* reread current character */
#define chartoint(ch) ((ch) & 0xff) /* make sure char is not negative */
@@ -410,6 +410,7 @@ homeexpand(char *name)
char *after; /* after the ~user or ~ */
char *username; /* extracted username */
size_t fullpath_len; /* length of fullpath */
size_t snprintf_len; /* malloced snprintf buffer length */
/* firewall */
if (name[0] != HOMECHAR)
@@ -466,11 +467,13 @@ homeexpand(char *name)
/*
* build the fullpath given the home directory
*/
fullpath = (char *)malloc(strlen(home2)+strlen(after)+1);
snprintf_len = strlen(home2)+strlen(after) + 1;
fullpath = (char *)malloc(snprintf_len+1);
if (fullpath == NULL) {
return NULL;
}
sprintf(fullpath, "%s%s", home2, after);
snprintf(fullpath, snprintf_len, "%s%s", home2, after);
fullpath[snprintf_len] = '\0'; /* paranoia */
return fullpath;
#endif /* Windoz free systems */
}
@@ -789,7 +792,7 @@ ttychar(void)
{
int ch; /* current char */
int len; /* length of current command */
STATIC char charbuf[1024];
STATIC char charbuf[256*1024];
/*
* If we have more to read from the saved command line, then do that.

View File

@@ -92,12 +92,6 @@
# include <stdlib.h>
#endif
#if defined(__linux)
# if !defined(isascii)
E_FUNC int isascii(int c);
# endif /* !isascii */
#endif /* __linux */
char *program; /* our name */
int

View File

@@ -83,7 +83,7 @@ math_error(char *fmt, ...)
#endif
vsnprintf(calc_err_msg, MAXERROR, fmt, ap);
va_end(ap);
calc_err_msg[MAXERROR] = '\0';
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
/*
* if we should longjmp, so do

42
qio.c
View File

@@ -62,12 +62,13 @@ qprintf(char *fmt, ...)
if (ch == '\\') {
ch = *fmt++;
switch (ch) {
case 'a': ch = '\a'; break;
case 'b': ch = '\b'; break;
case 'f': ch = '\f'; break;
case 'n': ch = '\n'; break;
case 'r': ch = '\r'; break;
case 't': ch = '\t'; break;
case 'f': ch = '\f'; break;
case 'v': ch = '\v'; break;
case 'b': ch = '\b'; break;
case 0:
va_end(ap);
return;
@@ -97,6 +98,15 @@ qprintf(char *fmt, ...)
q = va_arg(ap, NUMBER *);
qprintfe(q, width, precision);
break;
case 'g':
q = va_arg(ap, NUMBER *);
/* XXX - we need a qprintfg function */
#if 0 /* XXX - we need a qprintfg() function */
qprintfg(q, width, precision);
#else /* XXX - use qprintfe until we have a qprintfg() function */
qprintfe(q, width, precision);
#endif /* XXX - we need a qprintfg() function */
break;
case 'r':
case 'R':
q = va_arg(ap, NUMBER *);
@@ -174,7 +184,7 @@ qprintf(char *fmt, ...)
* Integers are always printed as themselves.
*/
void
qprintnum(NUMBER *q, int outmode)
qprintnum(NUMBER *q, int outmode, LEN outdigits)
{
NUMBER tmpval;
long prec, exp;
@@ -193,13 +203,13 @@ qprintnum(NUMBER *q, int outmode)
case MODE_REAL:
prec = qdecplaces(q);
if ((prec < 0) || (prec > conf->outdigits)) {
if ((prec < 0) || (prec > outdigits)) {
if (conf->tilde_ok)
PUTCHAR('~');
}
if (conf->fullzero || (prec < 0) ||
(prec > conf->outdigits))
prec = conf->outdigits;
(prec > outdigits))
prec = outdigits;
qprintff(q, 0L, prec);
break;
@@ -216,7 +226,7 @@ qprintnum(NUMBER *q, int outmode)
tmpval.num.sign = 0;
exp = qilog10(&tmpval);
if (exp == 0) { /* in range to output as real */
qprintnum(q, MODE_REAL);
qprintnum(q, MODE_REAL, outdigits);
return;
}
tmpval.num = _one_;
@@ -228,11 +238,25 @@ qprintnum(NUMBER *q, int outmode)
q = qmul(q, &tmpval);
zfree(tmpval.num);
zfree(tmpval.den);
qprintnum(q, MODE_REAL);
qprintnum(q, MODE_REAL, outdigits);
qfree(q);
PRINTF1("e%ld", exp);
break;
case MODE_REAL_AUTO:
{
const int P = conf->outdigits ? conf->outdigits : 1;
tmpval = *q;
tmpval.num.sign = 0;
exp = qilog10(&tmpval);
if (P > exp && exp >= -P) {
qprintnum(q, MODE_REAL, P - 1 - exp);
} else {
qprintnum(q, MODE_EXP, P - 1);
}
break;
}
case MODE_HEX:
qprintfx(q, 0L);
break;
@@ -252,7 +276,7 @@ qprintnum(NUMBER *q, int outmode)
if (outmode2 != MODE2_OFF) {
PUTSTR(" /* ");
qprintnum(q, outmode2);
qprintnum(q, outmode2, outdigits);
PUTSTR(" */");
}
}

View File

@@ -67,7 +67,7 @@ E_FUNC FULL qtou(NUMBER *q);
E_FUNC SFULL qtos(NUMBER *q);
E_FUNC long qparse(char *str, int flags);
E_FUNC void qfreenum(NUMBER *q);
E_FUNC void qprintnum(NUMBER *q, int mode);
E_FUNC void qprintnum(NUMBER *q, int mode, LEN outdigits);
E_FUNC void qprintff(NUMBER *q, long width, long precision);
E_FUNC void qprintfe(NUMBER *q, long width, long precision);
E_FUNC void qprintfr(NUMBER *q, long width, BOOL force);
@@ -254,7 +254,9 @@ E_FUNC NUMBER *swap_HALF_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all);
#define qhighbit(q) (zhighbit((q)->num))
#define qlowbit(q) (zlowbit((q)->num))
#define qdivcount(q1, q2) (zdivcount((q1)->num, (q2)->num))
#define qlink(q) ((q)->links++, (q))
/* operation on #q may be undefined, so replace with an inline-function */
/* was: #define qlink(q) ((q)->links++, (q)) */
static inline NUMBER* qlink(NUMBER* q) { if(q) { (q)->links++; } return q; }
#define qfree(q) {if (--((q)->links) <= 0) qfreenum(q);}

2
qmod.c
View File

@@ -404,7 +404,7 @@ showredcdata(void)
for (i = 0, rcp = redc_cache; i < MAXREDC; i++, rcp++) {
if (rcp->age > 0) {
printf("%-8ld%-8ld", i, rcp->age);
qprintnum(rcp->rnum, 0);
qprintnum(rcp->rnum, 0, conf->outdigits);
printf("\n");
}
}

3
sha1.c
View File

@@ -684,7 +684,7 @@ sha1_print(HASH *state)
* the last full update or finalization. Thus it
* may NOT be the actual hash value.
*/
sprintf(buf,
snprintf(buf, DEBUG_SIZE,
"sha1: 0x%08x%08x%08x%08x%08x data: %d octets",
(int)state->h_union.h_sha1.digest[0],
(int)state->h_union.h_sha1.digest[1],
@@ -692,6 +692,7 @@ sha1_print(HASH *state)
(int)state->h_union.h_sha1.digest[3],
(int)state->h_union.h_sha1.digest[4],
(int)state->h_union.h_sha1.datalen);
buf[DEBUG_SIZE] = '\0'; /* paranoia */
math_str(buf);
} else {
math_str("sha1 hash state");

19
str.c
View File

@@ -1380,17 +1380,17 @@ printechar(char *c)
math_chr('\\');
ech = 0;
switch (ch) {
case '\a': ech = 'a'; break;
case '\b': ech = 'b'; break;
case '\f': ech = 'f'; break;
case '\n': ech = 'n'; break;
case '\r': ech = 'r'; break;
case '\t': ech = 't'; break;
case '\b': ech = 'b'; break;
case '\f': ech = 'f'; break;
case '\v': ech = 'v'; break;
case '\\': ech = '\\'; break;
case '\"': ech = '\"'; break;
case '\'': ech = '\''; break;
case 0: ech = '0'; break;
case 7: ech = 'a'; break;
case 27: ech = 'e'; break;
}
if (ech == '0') {
@@ -1438,8 +1438,17 @@ fitstring(char *str, long len, long width)
continue;
n++;
switch (ch) {
case '\n': case '\r': case '\t': case '\b': case '\f':
case '\v': case '\\': case '\"': case 7: case 27:
case '\a':
case '\b':
case '\f':
case '\n':
case '\r':
case '\t':
case '\v':
case '\\':
case '\"':
case '\'':
case 27:
continue;
}
if (ch >= 64 || (nch >= '0' && nch <= '7')) {

18
token.c
View File

@@ -183,10 +183,12 @@ gettoken(void)
}
switch (ch) {
case ' ':
case '\t':
case '\r':
case '\v':
case '\a':
case '\b':
case '\f':
case '\r':
case '\t':
case '\v':
case '\0':
break;
case '\n':
@@ -718,7 +720,7 @@ scanerror(int skip, char *fmt, ...)
if (name) {
snprintf(calc_err_msg, MAXERROR, "\"%s\", line %ld: ",
name, linenumber());
calc_err_msg[MAXERROR] = '\0'; /* firewall */
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
len = strlen(calc_err_msg);
if (len < MAXERROR) {
vsnprintf(calc_err_msg+len, MAXERROR-len, fmt, ap);
@@ -727,7 +729,7 @@ scanerror(int skip, char *fmt, ...)
vsnprintf(calc_err_msg, MAXERROR, fmt, ap);
}
va_end(ap);
calc_err_msg[MAXERROR] = '\0';
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
/* print error message if allowed */
if (calc_print_scanerr_msg != 0) {
@@ -782,7 +784,7 @@ scanerror(int skip, char *fmt, ...)
default:
snprintf(calc_err_msg, MAXERROR,
"Unknown skip token for scanerror\n");
calc_err_msg[MAXERROR] = '\0';
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
if (calc_print_scanerr_msg != 0) {
fprintf(stderr, "%s\n\n", calc_err_msg);
}
@@ -823,7 +825,7 @@ warning(char *fmt, ...)
if (name) {
snprintf(calc_warn_msg, MAXERROR, "\"%s\", line %ld: ",
name, linenumber());
calc_warn_msg[MAXERROR] = '\0'; /* firewall */
calc_warn_msg[MAXERROR] = '\0'; /* paranoia */
len = strlen(calc_warn_msg);
if (len < MAXERROR) {
vsnprintf(calc_warn_msg+len, MAXERROR-len, fmt, ap);
@@ -832,7 +834,7 @@ warning(char *fmt, ...)
vsnprintf(calc_warn_msg, MAXERROR, fmt, ap);
}
va_end(ap);
calc_warn_msg[MAXERROR] = '\0';
calc_warn_msg[MAXERROR] = '\0'; /* paranoia */
/* print the warning if allowed */
if (calc_print_scanwarn_msg != 0) {

View File

@@ -2774,7 +2774,7 @@ printvalue(VALUE *vp, int flags)
}
switch (type) {
case V_NUM:
qprintnum(vp->v_num, MODE_DEFAULT);
qprintnum(vp->v_num, MODE_DEFAULT, conf->outdigits);
if (conf->traceflags & TRACE_LINKS)
math_fmt("#%ld", vp->v_num->links);
break;
@@ -2835,7 +2835,7 @@ printvalue(VALUE *vp, int flags)
if (userfunc("octet_print", vp))
break;
qtemp = itoq((long) *vp->v_octet);
qprintnum(qtemp, MODE_DEFAULT);
qprintnum(qtemp, MODE_DEFAULT, conf->outdigits);
qfree(qtemp);
break;
case V_OPTR:
@@ -2888,7 +2888,7 @@ printestr(VALUE *vp)
math_chr('"');
return;
case V_NUM:
qprintnum(vp->v_num, MODE_FRAC);
qprintnum(vp->v_num, MODE_FRAC, conf->outdigits);
return;
case V_COM:
mode = math_setmode(MODE_FRAC);
@@ -2944,7 +2944,7 @@ printestr(VALUE *vp)
bp = vp->v_nblock->blk;
}
i = bp->datalen;
math_fmt("%ld,%d)", i, bp->blkchunk);
math_fmt("%ld,%d)", i, (int) bp->blkchunk);
cp = bp->data;
if (i > 0) {
math_str("={");

View File

@@ -1,7 +1,7 @@
/*
* version - determine the version of calc
*
* Copyright (C) 1999-2017 David I. Bell and Landon Curt Noll
* Copyright (C) 1999-2018 David I. Bell and Landon Curt Noll
*
* Primary author: David I. Bell
*
@@ -44,8 +44,8 @@ static char *program;
#define MAJOR_VER 2 /* major library version */
#define MINOR_VER 12 /* minor library version */
#define MAJOR_PATCH 6 /* major software level under library version */
#define MINOR_PATCH 0 /* minor software level or 0 if not patched */
#define MAJOR_PATCH 7 /* major software level under library version */
#define MINOR_PATCH 1 /* minor software level or 0 if not patched */
/*
@@ -120,6 +120,7 @@ version(void)
snprintf(verbuf, BUFSIZ,
"%d.%d.%d.%d", calc_major_ver, calc_minor_ver,
calc_major_patch, calc_minor_patch);
verbuf[BUFSIZ] = '\0'; /* paranoia */
/*
* save the versions string into a newly malloced buffer

View File

@@ -1,5 +1,5 @@
TERMCONTROL=-DUSE_WIN32
HAVE_VSPRINTF=-UDONT_HAVE_VSPRINTF
HAVE_VSNPRINTF=-UDONT_HAVE_VSNPRINTF
BYTE_ORDER=-DLITTLE_ENDIAN
LONG_BITS=32
HAVE_FPOS=-DHAVE_NO_FPOS

175
zfunc.c
View File

@@ -1029,93 +1029,98 @@ zgcd(ZVALUE z1, ZVALUE z2, ZVALUE *res)
needw = FALSE;
}
g = *a0 * w;
if (h < BASEB) g &= (1 << h) - 1;
else g &= BASE1;
if (h < BASEB) {
g &= (1 << h) - 1;
} else {
g &= BASE1;
}
} else {
g = 1;
}
else g = 1;
} else
} else {
g = (HALF) *a0 * w;
a = a0;
b = b0;
i = n;
if (g > 1) { /* a - g * b case */
f = 0;
while (i--) {
f = (FULL) *a - g * *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
if (f) {
i = m - n;
while (i-- && f) {
f = *a - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
}
while (m && !*a0) { /* Removing trailing zeros */
m--;
a0++;
}
if (f) { /* a - g * b < 0 */
while (m > 1 && a0[m-1] == BASE1) m--;
*a0 = - *a0;
a = a0;
i = m;
while (--i) {
a++;
*a = ~*a;
}
}
} else { /* abs(a - b) case */
while (i && *a++ == *b++) i--;
q = n - i;
if (m == n) { /* a and b same length */
if (i) { /* a not equal to b */
while (m && a0[m-1] == b0[m-1]) m--;
if (a0[m-1] < b0[m-1]) {
/* Swapping since a < b */
a = a0;
a0 = b0;
b0 = a;
k = j;
}
a = a0 + q;
b = b0 + q;
i = m - q;
f = 0;
while (i--) {
f = (FULL) *a - *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
}
} else { /* a has more digits than b */
a = a0 + q;
b = b0 + q;
i = n - q;
f = 0;
while (i--) {
f = (FULL) *a - *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
if (f) { while (!*a) *a++ = BASE1;
(*a)--;
}
}
a0 += q;
m -= q;
while (m && !*a0) { /* Removing trailing zeros */
m--;
a0++;
}
}
while (m && !a0[m-1]) m--; /* Removing leading zeros */
}
a = a0;
b = b0;
i = n;
if (g > 1) { /* a - g * b case */
f = 0;
while (i--) {
f = (FULL) *a - g * *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
if (f) {
i = m - n;
while (i-- && f) {
f = *a - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
}
while (m && !*a0) { /* Removing trailing zeros */
m--;
a0++;
}
if (f) { /* a - g * b < 0 */
while (m > 1 && a0[m-1] == BASE1) m--;
*a0 = - *a0;
a = a0;
i = m;
while (--i) {
a++;
*a = ~*a;
}
}
} else { /* abs(a - b) case */
while (i && *a++ == *b++) i--;
q = n - i;
if (m == n) { /* a and b same length */
if (i) { /* a not equal to b */
while (m && a0[m-1] == b0[m-1]) m--;
if (a0[m-1] < b0[m-1]) {
/* Swapping since a < b */
a = a0;
a0 = b0;
b0 = a;
k = j;
}
a = a0 + q;
b = b0 + q;
i = m - q;
f = 0;
while (i--) {
f = (FULL) *a - *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
}
} else { /* a has more digits than b */
a = a0 + q;
b = b0 + q;
i = n - q;
f = 0;
while (i--) {
f = (FULL) *a - *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
if (f) { while (!*a) *a++ = BASE1;
(*a)--;
}
}
a0 += q;
m -= q;
while (m && !*a0) { /* Removing trailing zeros */
m--;
a0++;
}
}
while (m && !a0[m-1]) m--; /* Removing leading zeros */
}
if (m == 1) { /* a has one digit */
v = *a0;

2
zio.c
View File

@@ -177,7 +177,7 @@ math_fmt(char *fmt, ...)
va_start(ap, fmt);
vsnprintf(buf, BUFSIZ, fmt, ap);
va_end(ap);
buf[BUFSIZ] = '\0';
buf[BUFSIZ] = '\0'; /* paranoia */
math_str(buf);
}

View File

@@ -579,10 +579,16 @@ E_FUNC void zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res);
#define MODE_HEX 5
#define MODE_OCTAL 6
#define MODE_BINARY 7
#define MODE_MAX 7
#define MODE_REAL_AUTO 8
#define MODE_MAX 8
#define MODE2_OFF (MODE_MAX+1)
/* XXX - perhaps we need the MODE_REAL_AUTO vs MODE_REAL as a config mode? */
#if 0 /* XXX - can we safely set MODE_INITIAL to MODE_REAL_AUTO ?? */
#define MODE_INITIAL MODE_REAL_AUTO
#else
#define MODE_INITIAL MODE_REAL
#endif
#define MODE2_INITIAL MODE2_OFF