git: 46494d4edf98 - stable/13 - vendor/bc: import version 6.3.1
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 08 Jun 2023 10:57:15 UTC
The branch stable/13 has been updated by se:
URL: https://cgit.FreeBSD.org/src/commit/?id=46494d4edf9873fb31dc26d088f41482b341510d
commit 46494d4edf9873fb31dc26d088f41482b341510d
Author: Stefan Eßer <se@FreeBSD.org>
AuthorDate: 2023-02-24 22:14:58 +0000
Commit: Stefan Eßer <se@FreeBSD.org>
CommitDate: 2023-06-08 10:56:44 +0000
vendor/bc: import version 6.3.1
This version adds a command to dc to query whether extended registers
are enabled or not.
(cherry picked from commit 103d7cdfb7435591049413e1bc39482cb316efb7)
contrib/bc: import version 6.5.0
This release that fixes an infinite loop bug in the (non-standard)
extended math library functions root() and cbrt(), fixes a bug with
BC_LINE_LENGTH=0, and adds the fib() function to the extended math
library to calculate Fibonacci numbers.
(cherry picked from commit 8c48f4c5377ddc3dc55388f181f23111145f7099)
contrib/bc: upgrade to version 6.6.0
This update removes printing of a leading zero in scientific or
engineering output modes (which are an extended feature of this
implementation).
(cherry picked from commit 76238846ad3e9e271a3d1f792f72beab727fd153)
---
contrib/bc/LICENSE.md | 2 +-
contrib/bc/MEMORY_BUGS.md | 5 +
contrib/bc/Makefile.in | 12 +-
contrib/bc/NEWS.md | 62 +++
contrib/bc/README.md | 18 +-
contrib/bc/configure.sh | 34 +-
contrib/bc/gen/lib2.bc | 28 +-
contrib/bc/gen/strgen.c | 6 +-
contrib/bc/gen/strgen.sh | 4 +-
contrib/bc/include/bcl.h | 57 +++
contrib/bc/include/lang.h | 7 +-
contrib/bc/include/lex.h | 17 +-
contrib/bc/include/library.h | 210 ++++++--
contrib/bc/include/num.h | 8 +
contrib/bc/include/parse.h | 14 +-
contrib/bc/include/program.h | 218 +++-----
contrib/bc/include/rand.h | 6 +-
contrib/bc/include/status.h | 31 +-
contrib/bc/include/vector.h | 4 +-
contrib/bc/include/version.h | 2 +-
contrib/bc/include/vm.h | 10 +-
contrib/bc/manuals/bc/A.1 | 6 +-
contrib/bc/manuals/bc/A.1.md | 2 +-
contrib/bc/manuals/bc/E.1 | 6 +-
contrib/bc/manuals/bc/E.1.md | 2 +-
contrib/bc/manuals/bc/EH.1 | 6 +-
contrib/bc/manuals/bc/EH.1.md | 2 +-
contrib/bc/manuals/bc/EHN.1 | 6 +-
contrib/bc/manuals/bc/EHN.1.md | 2 +-
contrib/bc/manuals/bc/EN.1 | 6 +-
contrib/bc/manuals/bc/EN.1.md | 2 +-
contrib/bc/manuals/bc/H.1 | 6 +-
contrib/bc/manuals/bc/H.1.md | 2 +-
contrib/bc/manuals/bc/HN.1 | 6 +-
contrib/bc/manuals/bc/HN.1.md | 2 +-
contrib/bc/manuals/bc/N.1 | 6 +-
contrib/bc/manuals/bc/N.1.md | 2 +-
contrib/bc/manuals/bcl.3 | 424 +++++++++++++++-
contrib/bc/manuals/bcl.3.md | 320 +++++++++++-
contrib/bc/manuals/dc/A.1 | 12 +-
contrib/bc/manuals/dc/A.1.md | 10 +-
contrib/bc/manuals/dc/E.1 | 12 +-
contrib/bc/manuals/dc/E.1.md | 10 +-
contrib/bc/manuals/dc/EH.1 | 12 +-
contrib/bc/manuals/dc/EH.1.md | 10 +-
contrib/bc/manuals/dc/EHN.1 | 12 +-
contrib/bc/manuals/dc/EHN.1.md | 10 +-
contrib/bc/manuals/dc/EN.1 | 12 +-
contrib/bc/manuals/dc/EN.1.md | 10 +-
contrib/bc/manuals/dc/H.1 | 12 +-
contrib/bc/manuals/dc/H.1.md | 10 +-
contrib/bc/manuals/dc/HN.1 | 12 +-
contrib/bc/manuals/dc/HN.1.md | 10 +-
contrib/bc/manuals/dc/N.1 | 12 +-
contrib/bc/manuals/dc/N.1.md | 10 +-
contrib/bc/scripts/exec-install.sh | 6 +
contrib/bc/scripts/format.sh | 2 +
contrib/bc/scripts/link.sh | 5 +
contrib/bc/scripts/lint.sh | 5 +-
contrib/bc/scripts/locale_install.sh | 3 +-
contrib/bc/scripts/safe-install.sh | 12 +-
contrib/bc/src/args.c | 4 +-
contrib/bc/src/bc_parse.c | 6 +-
contrib/bc/src/data.c | 77 +--
contrib/bc/src/dc_lex.c | 1 +
contrib/bc/src/dc_parse.c | 1 +
contrib/bc/src/file.c | 4 +-
contrib/bc/src/history.c | 4 +-
contrib/bc/src/lang.c | 8 +-
contrib/bc/src/library.c | 743 +++++++++++++++++++---------
contrib/bc/src/num.c | 95 +++-
contrib/bc/src/parse.c | 4 +-
contrib/bc/src/program.c | 75 ++-
contrib/bc/src/rand.c | 5 +-
contrib/bc/src/read.c | 4 +-
contrib/bc/src/vm.c | 44 +-
contrib/bc/tests/all.sh | 3 +-
contrib/bc/tests/bc/all.txt | 2 +
contrib/bc/tests/bc/fib.txt | 31 ++
contrib/bc/tests/bc/fib_results.txt | 31 ++
contrib/bc/tests/bc/rand_limits.txt | 284 +++++++++++
contrib/bc/tests/bc/rand_limits_results.txt | 222 +++++++++
contrib/bc/tests/bc/scripts/all.txt | 1 +
contrib/bc/tests/bc/scripts/cbrt.txt | 100 ++++
contrib/bc/tests/bc/scripts/root.bc | 19 +
contrib/bc/tests/bc/scripts/root.txt | 255 ++++++++++
contrib/bc/tests/bcl.c | 52 +-
contrib/bc/tests/error.sh | 8 +-
contrib/bc/tests/errors.sh | 8 +-
contrib/bc/tests/extra_required.txt | 2 +
contrib/bc/tests/other.sh | 120 +++--
contrib/bc/tests/read.sh | 13 +
contrib/bc/tests/script.sh | 20 +-
contrib/bc/tests/scripts.sh | 5 +-
contrib/bc/tests/test.sh | 6 +-
contrib/bc/vs/bc.vcxproj | 2 +-
usr.bin/gh-bc/Makefile | 43 +-
usr.bin/gh-bc/tests/Makefile | 4 +-
98 files changed, 3293 insertions(+), 785 deletions(-)
diff --git a/contrib/bc/LICENSE.md b/contrib/bc/LICENSE.md
index b65095edc26c..74441065df35 100644
--- a/contrib/bc/LICENSE.md
+++ b/contrib/bc/LICENSE.md
@@ -59,7 +59,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The files `src/rand.c` and `include/rand.h` are under the following copyrights
and license:
-Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
+Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors<br>
Copyright (c) 2018-2023 Gavin D. Howard <gavin@gavinhoward.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/contrib/bc/MEMORY_BUGS.md b/contrib/bc/MEMORY_BUGS.md
index d675b28b342a..12e0b854e9d8 100644
--- a/contrib/bc/MEMORY_BUGS.md
+++ b/contrib/bc/MEMORY_BUGS.md
@@ -51,3 +51,8 @@ existed in.
had properly hooked Valgrind into my `bcl` tests, but I had not.
The first version without this bug is `6.0.1`.
+
+* In version `6.0.0` until `6.2.4` (inclusive) of `bcl`, there is a possible
+ use-after-free if `bcl_init()` fails.
+
+ The first version without this bug is `6.2.5`.
diff --git a/contrib/bc/Makefile.in b/contrib/bc/Makefile.in
index 83417a333826..55e2e4a6270a 100644
--- a/contrib/bc/Makefile.in
+++ b/contrib/bc/Makefile.in
@@ -205,7 +205,7 @@ DC_DEFS = $(DC_DEFS1) $(DC_DEFS2) $(DC_DEFS3) $(DC_DEFS4) $(DC_DEFS5)
CPPFLAGS1 = -D$(BC_ENABLED_NAME)=$(BC_ENABLED) -D$(DC_ENABLED_NAME)=$(DC_ENABLED)
CPPFLAGS2 = $(CPPFLAGS1) -I$(INCDIR)/ -DBUILD_TYPE=$(BC_BUILD_TYPE) %%LONG_BIT_DEFINE%%
CPPFLAGS3 = $(CPPFLAGS2) -DEXECPREFIX=$(EXEC_PREFIX) -DMAINEXEC=$(MAIN_EXEC)
-CPPFLAGS4 = $(CPPFLAGS3) %%BSD%%
+CPPFLAGS4 = $(CPPFLAGS3) %%BSD%% %%APPLE%%
CPPFLAGS5 = $(CPPFLAGS4) -DBC_NUM_KARATSUBA_LEN=$(BC_NUM_KARATSUBA_LEN)
CPPFLAGS6 = $(CPPFLAGS5) -DBC_ENABLE_NLS=$(BC_ENABLE_NLS)
CPPFLAGS7 = $(CPPFLAGS6) -D$(BC_ENABLE_EXTRA_MATH_NAME)=$(BC_ENABLE_EXTRA_MATH)
@@ -239,25 +239,25 @@ $(GEN_EXEC): $(GEN_DIR)
%%GEN_EXEC_TARGET%%
$(BC_LIB_C): $(GEN_EXEC) $(BC_LIB)
- $(GEN_EMU) $(GEN_EXEC) $(BC_LIB) $(BC_LIB_C) $(BC_EXCLUDE_EXTRA_MATH) $(BC_LIB_C_ARGS)
+ $(GEN_EMU) $(GEN_EXEC) $(BC_LIB) $(BC_LIB_C) $(BC_EXCLUDE_EXTRA_MATH) $(BC_LIB_C_ARGS) "" "" 1
$(BC_LIB_O): $(BC_LIB_C)
$(CC) $(CFLAGS) -o $@ -c $<
$(BC_LIB2_C): $(GEN_EXEC) $(BC_LIB2)
- $(GEN_EMU) $(GEN_EXEC) $(BC_LIB2) $(BC_LIB2_C) $(BC_EXCLUDE_EXTRA_MATH) $(BC_LIB2_C_ARGS)
+ $(GEN_EMU) $(GEN_EXEC) $(BC_LIB2) $(BC_LIB2_C) $(BC_EXCLUDE_EXTRA_MATH) $(BC_LIB2_C_ARGS) "" "" 1
$(BC_LIB2_O): $(BC_LIB2_C)
$(CC) $(CFLAGS) -o $@ -c $<
$(BC_HELP_C): $(GEN_EXEC) $(BC_HELP)
- $(GEN_EMU) $(GEN_EXEC) $(BC_HELP) $(BC_HELP_C) $(BC_EXCLUDE_EXTRA_MATH) bc_help "" $(BC_ENABLED_NAME)
+ $(GEN_EMU) $(GEN_EXEC) $(BC_HELP) $(BC_HELP_C) $(BC_EXCLUDE_EXTRA_MATH) bc_help "" $(BC_ENABLED_NAME) 0
$(BC_HELP_O): $(BC_HELP_C)
$(CC) $(CFLAGS) -o $@ -c $<
$(DC_HELP_C): $(GEN_EXEC) $(DC_HELP)
- $(GEN_EMU) $(GEN_EXEC) $(DC_HELP) $(DC_HELP_C) $(BC_EXCLUDE_EXTRA_MATH) dc_help "" $(DC_ENABLED_NAME)
+ $(GEN_EMU) $(GEN_EXEC) $(DC_HELP) $(DC_HELP_C) $(BC_EXCLUDE_EXTRA_MATH) dc_help "" $(DC_ENABLED_NAME) 0
$(DC_HELP_O): $(DC_HELP_C)
$(CC) $(CFLAGS) -o $@ -c $<
@@ -548,6 +548,8 @@ clean_config: clean clean_benchmarks
@$(RM) -f Makefile
@$(RM) -f $(BC_MD) $(BC_MANPAGE)
@$(RM) -f $(DC_MD) $(DC_MANPAGE)
+ @$(RM) -f compile_commands.json
+ @$(RM) -f $(BCL_PC)
clean_coverage:
@printf 'Cleaning coverage files...\n'
diff --git a/contrib/bc/NEWS.md b/contrib/bc/NEWS.md
index 4601db456f86..de3b35026fea 100644
--- a/contrib/bc/NEWS.md
+++ b/contrib/bc/NEWS.md
@@ -1,5 +1,67 @@
# News
+## 6.6.0
+
+This is a production release with two bug fixes and one change.
+
+The first bug fix is to fix the build on Mac OSX.
+
+The second bug was to remove printing a leading zero in scientific or
+engineering output modes.
+
+The change was that the implementation of `irand()` was improved to call the
+PRNG less.
+
+## 6.5.0
+
+This is a production release that fixes an infinite loop bug in `root()` and
+`cbrt()`, fixes a bug with `BC_LINE_LENGTH=0`, and adds the `fib()` function to
+the extended math library to calculate Fibonacci numbers.
+
+## 6.4.0
+
+This is a production release that fixes a `read()`/`?` bug and adds features to
+`bcl`.
+
+The bug was that multiple read calls could repeat old data.
+
+The new features in `bcl` are functions to preserve `BclNumber` arguments and
+not free them.
+
+***WARNING for `bcl` Users***: The `bcl_rand_seedWithNum()` function used to not
+consume its arguments. Now it does. This change could have made this version
+`7.0.0`, but I'm 99.9% confident that there are no `bcl` users, or if there are,
+they probably don't use the PRNG. So I took a risk and didn't update the major
+version.
+
+`bcl` now includes more capacity to check for invalid numbers when built to run
+under Valgrind.
+
+## 6.3.1
+
+This is a production release that fixes a `bc` dependency loop for minimal
+environments and Linux from Scratch.
+
+## 6.3.0
+
+This is a production release with a couple of fixes for manuals and a new
+feature for `dc`: there is now a command to query whether extended registers are
+enabled or not.
+
+Users who don't care do not need to upgrade.
+
+## 6.2.6
+
+This is a production release that fixes an install bug that affected locale
+installation of all locales when using `mksh`. Users do ***NOT*** need to
+upgrade if they don't use `mksh` and/or don't need to install all locales.
+
+## 6.2.5
+
+This is a production release that fixes a test bug that affected Android and
+`mksh`. Users do ***NOT*** need to upgrade unless they use `mksh` or another
+affected shell and need to run the test suite.
+
## 6.2.4
This is a production release that fixes a test failure that happens when
diff --git a/contrib/bc/README.md b/contrib/bc/README.md
index 9d395f747185..943ca89eee2c 100644
--- a/contrib/bc/README.md
+++ b/contrib/bc/README.md
@@ -422,13 +422,23 @@ Other projects based on this bc are:
* [busybox `bc`][8]. The busybox maintainers have made their own changes, so any
bugs in the busybox `bc` should be reported to them.
-
* [toybox `bc`][9]. The maintainer has also made his own changes, so bugs in the
toybox `bc` should be reported there.
-
* [FreeBSD `bc`][23]. While the `bc` in FreeBSD is kept up-to-date, it is better
to [report bugs there][24], as well as [submit patches][25], and the
maintainers of the package will contact me if necessary.
+* [Mac OSX `bc`][35]. Any bugs in that `bc` should be reported to me, but do
+ expect bugs because the version is old.
+* [Android Open Source `bc`][32]. Any bugs in that `bc` can be reported here.
+
+This is a non-comprehensive list of Linux distros that use this `bc` as the
+system `bc`:
+
+* [Gentoo][33]; it is a first-class alternative to GNU `bc`, but not exclusive.
+* [Linux from Scratch][34].
+
+Other Linux distros package it as a second-class alternative, usually as `bc-gh`
+or `howard-bc`.
## Language
@@ -500,3 +510,7 @@ Folders:
[29]: https://github.com/gavinhoward/bc
[30]: ./manuals/bc/A.1.md#extended-library
[31]: ./manuals/build.md#settings
+[32]: https://android.googlesource.com/platform/external/bc/
+[33]: https://github.com/gentoo/gentoo/blob/master/app-alternatives/bc/bc-0.ebuild#L8
+[34]: https://www.linuxfromscratch.org/lfs/view/stable/chapter08/bc.html
+[35]: https://github.com/apple-oss-distributions/bc/tree/main/bc
diff --git a/contrib/bc/configure.sh b/contrib/bc/configure.sh
index 3ada5298e9ed..4ba957131d52 100755
--- a/contrib/bc/configure.sh
+++ b/contrib/bc/configure.sh
@@ -772,7 +772,7 @@ predefined_build() {
dc_default_digit_clamp=0;;
GDH)
- CFLAGS="-flto -Weverything -Wno-padded -Werror -pedantic -std=c11"
+ CFLAGS="-flto -Weverything -Wno-padded -Wno-unsafe-buffer-usage -Werror -pedantic -std=c11"
bc_only=0
dc_only=0
coverage=0
@@ -806,7 +806,7 @@ predefined_build() {
dc_default_digit_clamp=1;;
DBG)
- CFLAGS="-Weverything -Wno-padded -Werror -pedantic -std=c11"
+ CFLAGS="-Weverything -Wno-padded -Wno-unsafe-buffer-usage -Werror -pedantic -std=c11"
bc_only=0
dc_only=0
coverage=0
@@ -1653,12 +1653,12 @@ else
# We are also setting the CFLAGS and LDFLAGS here.
if [ "$editline" -ne 0 ]; then
LDFLAGS="$LDFLAGS -ledit"
- CFLAGS="$CFLAGS -DBC_ENABLE_EDITLINE=1 -DBC_ENABLE_READLINE=0"
+ CPPFLAGS="$CPPFLAGS -DBC_ENABLE_EDITLINE=1 -DBC_ENABLE_READLINE=0"
elif [ "$readline" -ne 0 ]; then
LDFLAGS="$LDFLAGS -lreadline"
- CFLAGS="$CFLAGS -DBC_ENABLE_EDITLINE=0 -DBC_ENABLE_READLINE=1"
+ CPPFLAGS="$CPPFLAGS -DBC_ENABLE_EDITLINE=0 -DBC_ENABLE_READLINE=1"
else
- CFLAGS="$CFLAGS -DBC_ENABLE_EDITLINE=0 -DBC_ENABLE_READLINE=0"
+ CPPFLAGS="$CPPFLAGS -DBC_ENABLE_EDITLINE=0 -DBC_ENABLE_READLINE=0"
fi
fi
@@ -1682,6 +1682,24 @@ else
CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
fi
+# Test Mac OSX. This is not in an if statement because regardless of whatever
+# the user says, we need to know if we are on Mac OSX. If we are, we have to set
+# _DARWIN_C_SOURCE.
+printf 'Testing for Mac OSX...\n'
+
+flags="-DBC_TEST_APPLE -DBC_ENABLE_AFL=0"
+"$CC" $CPPFLAGS $CFLAGS $flags "-I$scriptdir/include" -E "$scriptdir/src/vm.c" > /dev/null 2>&1
+
+err="$?"
+
+if [ "$err" -ne 0 ]; then
+ printf 'On Mac OSX. Using _DARWIN_C_SOURCE.\n\n'
+ apple="-D_DARWIN_C_SOURCE"
+else
+ printf 'Not on Mac OSX.\n\n'
+ apple=""
+fi
+
# Test OpenBSD. This is not in an if statement because regardless of whatever
# the user says, we need to know if we are on OpenBSD to activate _BSD_SOURCE.
# No, I cannot `#define _BSD_SOURCE` in a header because OpenBSD's patched GCC
@@ -1690,7 +1708,6 @@ fi
# we have to set it because we also set _POSIX_C_SOURCE, which OpenBSD headers
# detect, and when they detect it, they turn off _BSD_SOURCE unless it is
# specifically requested.
-set +e
printf 'Testing for OpenBSD...\n'
flags="-DBC_TEST_OPENBSD -DBC_ENABLE_AFL=0"
@@ -1713,6 +1730,8 @@ else
bsd=""
fi
+set -e
+
if [ "$library" -eq 1 ]; then
bc_lib=""
fi
@@ -1801,7 +1820,7 @@ if [ "$library" -ne 0 ]; then
contents=$(replace "$contents" "LIBDIR" "$LIBDIR")
contents=$(replace "$contents" "VERSION" "$version")
- printf '%s\n' "$contents" > "./bcl.pc"
+ printf '%s\n' "$contents" > "$scriptdir/bcl.pc"
pkg_config_install="\$(SAFE_INSTALL) \$(PC_INSTALL_ARGS) \"\$(BCL_PC)\" \"\$(DESTDIR)\$(PC_PATH)/\$(BCL_PC)\""
pkg_config_uninstall="\$(RM) -f \"\$(DESTDIR)\$(PC_PATH)/\$(BCL_PC)\""
@@ -2072,6 +2091,7 @@ contents=$(replace "$contents" "CLEAN_PREREQS" "$CLEAN_PREREQS")
contents=$(replace "$contents" "GEN_EMU" "$GEN_EMU")
contents=$(replace "$contents" "BSD" "$bsd")
+contents=$(replace "$contents" "APPLE" "$apple")
contents=$(replace "$contents" "BC_DEFAULT_BANNER" "$bc_default_banner")
contents=$(replace "$contents" "BC_DEFAULT_SIGINT_RESET" "$bc_default_sigint_reset")
diff --git a/contrib/bc/gen/lib2.bc b/contrib/bc/gen/lib2.bc
index 826f8a430cea..ba3f76b1803a 100644
--- a/contrib/bc/gen/lib2.bc
+++ b/contrib/bc/gen/lib2.bc
@@ -36,7 +36,7 @@
define p(x,y){
auto a
a=y$
- if(y==a)return (x^a)@scale
+ if(y==a)return(x^a)@scale
return e(y*l(x))
}
define r(x,p){
@@ -93,6 +93,18 @@ define comb(n,r){
scale=s
return f
}
+define fib(n){
+ auto i,t,p,r
+ if(!n)return 0
+ n=abs(n)$
+ t=1
+ for (i=1;i<n;++i){
+ r=p
+ p=t
+ t+=r
+ }
+ return t
+}
define log(x,b){
auto p,s
s=scale
@@ -106,7 +118,7 @@ define log(x,b){
define l2(x){return log(x,2)}
define l10(x){return log(x,A)}
define root(x,n){
- auto s,m,r,q,p
+ auto s,t,m,r,q,p
if(n<0)sqrt(n)
n=n$
if(n==0)x/n
@@ -114,13 +126,17 @@ define root(x,n){
if(n==2)return sqrt(x)
s=scale
scale=0
- if(x<0&&n%2==0)sqrt(x)
- scale=s+2
+ if(x<0&&n%2==0){
+ scale=s
+ sqrt(x)
+ }
+ scale=s+scale(x)+5
+ t=s+5
m=(x<0)
x=abs(x)
p=n-1
q=A^ceil((length(x$)/n)$,0)
- while(r!=q){
+ while(r@t!=q@t){
r=q
q=(p*r+x/r^p)/n
}
@@ -474,7 +490,7 @@ define bxor(a,b){
return bunrev(t)
}
define bshl(a,b){return abs(a)$*2^abs(b)$}
-define bshr(a,b){return (abs(a)$/2^abs(b)$)$}
+define bshr(a,b){return(abs(a)$/2^abs(b)$)$}
define bnotn(x,n){
auto s,t,m[]
s=scale
diff --git a/contrib/bc/gen/strgen.c b/contrib/bc/gen/strgen.c
index dbea0212f617..2cb3ed9e8475 100644
--- a/contrib/bc/gen/strgen.c
+++ b/contrib/bc/gen/strgen.c
@@ -157,11 +157,11 @@ bc_read_file(const char* path)
assert(path != NULL);
-#ifndef NDEBUG
+#if BC_DEBUG
// Need this to quiet MSan.
// NOLINTNEXTLINE
memset(&pstat, 0, sizeof(struct stat));
-#endif // NDEBUG
+#endif // BC_DEBUG
fd = bc_read_open(path, O_RDONLY);
@@ -360,7 +360,7 @@ main(int argc, char* argv[])
has_define = (argc > 6 && strcmp("", argv[6]) != 0);
define = has_define ? argv[6] : "";
- remove_tabs = (argc > 7);
+ remove_tabs = (argc > 7 && atoi(argv[7]) != 0);
in = bc_read_file(argv[1]);
if (in == NULL) return INVALID_INPUT_FILE;
diff --git a/contrib/bc/gen/strgen.sh b/contrib/bc/gen/strgen.sh
index a65e221ad0b4..2b8927b5528e 100755
--- a/contrib/bc/gen/strgen.sh
+++ b/contrib/bc/gen/strgen.sh
@@ -62,7 +62,9 @@ name="$4"
label="$5"
define="$6"
remove_tabs="$7"
-check_bool_arg "$remove_tabs"
+if [ "$remove_tabs" != "" ]; then
+ check_bool_arg "$remove_tabs"
+fi
tmpinput=$(mktemp -t "${input##*/}_XXXXXX")
diff --git a/contrib/bc/include/bcl.h b/contrib/bc/include/bcl.h
index 234fe475f00e..0908e215182c 100644
--- a/contrib/bc/include/bcl.h
+++ b/contrib/bc/include/bcl.h
@@ -36,11 +36,20 @@
#ifndef BC_BCL_H
#define BC_BCL_H
+// TODO: Add a generation index when building with Valgrind to check for
+// use-after-free's or double frees.
+
#include <stdbool.h>
#include <stdlib.h>
#include <limits.h>
#include <stdint.h>
+#ifndef NDEBUG
+#define BC_DEBUG (1)
+#else // NDEBUG
+#define BC_DEBUG (0)
+#endif // NDEBUG
+
#ifdef _WIN32
#include <Windows.h>
#include <BaseTsd.h>
@@ -232,42 +241,78 @@ bcl_dup(BclNumber s);
BclError
bcl_bigdig(BclNumber n, BclBigDig* result);
+BclError
+bcl_bigdig_keep(BclNumber n, BclBigDig* result);
+
BclNumber
bcl_bigdig2num(BclBigDig val);
BclNumber
bcl_add(BclNumber a, BclNumber b);
+BclNumber
+bcl_add_keep(BclNumber a, BclNumber b);
+
BclNumber
bcl_sub(BclNumber a, BclNumber b);
+BclNumber
+bcl_sub_keep(BclNumber a, BclNumber b);
+
BclNumber
bcl_mul(BclNumber a, BclNumber b);
+BclNumber
+bcl_mul_keep(BclNumber a, BclNumber b);
+
BclNumber
bcl_div(BclNumber a, BclNumber b);
+BclNumber
+bcl_div_keep(BclNumber a, BclNumber b);
+
BclNumber
bcl_mod(BclNumber a, BclNumber b);
+BclNumber
+bcl_mod_keep(BclNumber a, BclNumber b);
+
BclNumber
bcl_pow(BclNumber a, BclNumber b);
+BclNumber
+bcl_pow_keep(BclNumber a, BclNumber b);
+
BclNumber
bcl_lshift(BclNumber a, BclNumber b);
+BclNumber
+bcl_lshift_keep(BclNumber a, BclNumber b);
+
BclNumber
bcl_rshift(BclNumber a, BclNumber b);
+BclNumber
+bcl_rshift_keep(BclNumber a, BclNumber b);
+
BclNumber
bcl_sqrt(BclNumber a);
+BclNumber
+bcl_sqrt_keep(BclNumber a);
+
BclError
bcl_divmod(BclNumber a, BclNumber b, BclNumber* c, BclNumber* d);
+BclError
+bcl_divmod_keep(BclNumber a, BclNumber b, BclNumber* c, BclNumber* d);
+
BclNumber
bcl_modexp(BclNumber a, BclNumber b, BclNumber c);
+BclNumber
+bcl_modexp_keep(BclNumber a, BclNumber b, BclNumber c);
+
ssize_t
bcl_cmp(BclNumber a, BclNumber b);
@@ -283,18 +328,30 @@ bcl_parse(const char* restrict val);
char*
bcl_string(BclNumber n);
+char*
+bcl_string_keep(BclNumber n);
+
BclNumber
bcl_irand(BclNumber a);
+BclNumber
+bcl_irand_keep(BclNumber a);
+
BclNumber
bcl_frand(size_t places);
BclNumber
bcl_ifrand(BclNumber a, size_t places);
+BclNumber
+bcl_ifrand_keep(BclNumber a, size_t places);
+
BclError
bcl_rand_seedWithNum(BclNumber n);
+BclError
+bcl_rand_seedWithNum_keep(BclNumber n);
+
BclError
bcl_rand_seed(unsigned char seed[BCL_SEED_SIZE]);
diff --git a/contrib/bc/include/lang.h b/contrib/bc/include/lang.h
index 2d9776532249..97aeeaa98da8 100644
--- a/contrib/bc/include/lang.h
+++ b/contrib/bc/include/lang.h
@@ -277,6 +277,9 @@ typedef enum BcInst
#if DC_ENABLED
+ /// dc extended registers command.
+ BC_INST_EXTENDED_REGISTERS,
+
/// dc's return; it pops an executing string off of the stack.
BC_INST_POP_EXEC,
@@ -575,7 +578,7 @@ bc_func_insert(BcFunc* f, struct BcProgram* p, char* name, BcType type,
void
bc_func_reset(BcFunc* f);
-#ifndef NDEBUG
+#if BC_DEBUG
/**
* Frees a function. This is a destructor. This is only used in debug builds
* because all functions are freed at exit. We free them in debug builds to
@@ -584,7 +587,7 @@ bc_func_reset(BcFunc* f);
*/
void
bc_func_free(void* func);
-#endif // NDEBUG
+#endif // BC_DEBUG
/**
* Initializes an array, which is the array type in bc and dc source code. Since
diff --git a/contrib/bc/include/lex.h b/contrib/bc/include/lex.h
index 54d704f8b447..ac9b7b6ea69c 100644
--- a/contrib/bc/include/lex.h
+++ b/contrib/bc/include/lex.h
@@ -49,11 +49,11 @@
* @param l The lexer.
* @param e The error.
*/
-#ifndef NDEBUG
+#if BC_DEBUG
#define bc_lex_err(l, e) (bc_vm_handleError((e), __FILE__, __LINE__, (l)->line))
-#else // NDEBUG
+#else // BC_DEBUG
#define bc_lex_err(l, e) (bc_vm_handleError((e), (l)->line))
-#endif // NDEBUG
+#endif // BC_DEBUG
/**
* A convenience macro for throwing errors in lex code. This takes care of
@@ -61,12 +61,12 @@
* @param l The lexer.
* @param e The error.
*/
-#ifndef NDEBUG
+#if BC_DEBUG
#define bc_lex_verr(l, e, ...) \
(bc_vm_handleError((e), __FILE__, __LINE__, (l)->line, __VA_ARGS__))
-#else // NDEBUG
+#else // BC_DEBUG
#define bc_lex_verr(l, e, ...) (bc_vm_handleError((e), (l)->line, __VA_ARGS__))
-#endif // NDEBUG
+#endif // BC_DEBUG
// BC_LEX_NEG_CHAR returns the char that corresponds to negative for the
// current calculator.
@@ -409,6 +409,9 @@ typedef enum BcLexType
#if DC_ENABLED
+ /// dc extended registers keyword.
+ BC_LEX_EXTENDED_REGISTERS,
+
/// A special token for dc to calculate equal without a register.
BC_LEX_EQ_NO_REG,
@@ -533,7 +536,7 @@ void
bc_lex_init(BcLex* l);
/**
- * Frees a lexer. This is not guarded by #ifndef NDEBUG because a separate
+ * Frees a lexer. This is not guarded by #if BC_DEBUG because a separate
* parser is created at runtime to parse read() expressions and dc strings, and
* that parser needs a lexer.
* @param l The lexer to free.
diff --git a/contrib/bc/include/library.h b/contrib/bc/include/library.h
index 76df91392da1..1edd3757444c 100644
--- a/contrib/bc/include/library.h
+++ b/contrib/bc/include/library.h
@@ -47,6 +47,145 @@
#include <num.h>
#include <vm.h>
+#if BC_ENABLE_MEMCHECK
+
+/**
+ * A typedef for Valgrind builds. This is to add a generation index for error
+ * checking.
+ */
+typedef struct BclNum
+{
+ /// The number.
+ BcNum n;
+
+ /// The generation index.
+ size_t gen_idx;
+
+} BclNum;
+
+/**
+ * Clears the generation byte in a BclNumber and returns the value.
+ * @param n The BclNumber.
+ * @return The value of the index.
+ */
+#define BCL_NO_GEN(n) \
+ ((n).i & ~(((size_t) UCHAR_MAX) << ((sizeof(size_t) - 1) * CHAR_BIT)))
+
+/**
+ * Gets the generation index in a BclNumber.
+ * @param n The BclNumber.
+ * @return The generation index.
+ */
+#define BCL_GET_GEN(n) ((n).i >> ((sizeof(size_t) - 1) * CHAR_BIT))
+
+/**
+ * Turns a BclNumber into a BcNum.
+ * @param c The context.
+ * @param n The BclNumber.
+ */
+#define BCL_NUM(c, n) ((BclNum*) bc_vec_item(&(c)->nums, BCL_NO_GEN(n)))
+
+/**
+ * Clears the generation index top byte in the BclNumber.
+ * @param n The BclNumber.
+ */
+#define BCL_CLEAR_GEN(n) \
+ do \
+ { \
+ (n).i &= ~(((size_t) UCHAR_MAX) << ((sizeof(size_t) - 1) * CHAR_BIT)); \
+ } \
+ while (0)
+
+#define BCL_CHECK_NUM_GEN(c, bn) \
+ do \
+ { \
+ size_t gen_ = BCL_GET_GEN(bn); \
+ BclNum* ptr_ = BCL_NUM(c, bn); \
+ if (BCL_NUM_ARRAY(ptr_) == NULL) \
+ { \
+ bcl_nonexistentNum(); \
+ } \
+ if (gen_ != ptr_->gen_idx) \
+ { \
+ bcl_invalidGeneration(); \
+ } \
+ } \
+ while (0)
+
+#define BCL_CHECK_NUM_VALID(c, bn) \
+ do \
+ { \
+ size_t idx_ = BCL_NO_GEN(bn); \
+ if ((c)->nums.len <= idx_) \
+ { \
+ bcl_numIdxOutOfRange(); \
+ } \
+ BCL_CHECK_NUM_GEN(c, bn); \
+ } \
+ while (0)
+
+/**
+ * Returns the limb array of the number.
+ * @param bn The number.
+ * @return The limb array.
+ */
+#define BCL_NUM_ARRAY(bn) ((bn)->n.num)
+
+/**
+ * Returns the limb array of the number for a non-pointer.
+ * @param bn The number.
+ * @return The limb array.
+ */
+#define BCL_NUM_ARRAY_NP(bn) ((bn).n.num)
+
+/**
+ * Returns the BcNum pointer.
+ * @param bn The number.
+ * @return The BcNum pointer.
+ */
+#define BCL_NUM_NUM(bn) (&(bn)->n)
+
+/**
+ * Returns the BcNum pointer for a non-pointer.
+ * @param bn The number.
+ * @return The BcNum pointer.
+ */
+#define BCL_NUM_NUM_NP(bn) (&(bn).n)
+
+// These functions only abort. They exist to give developers some idea of what
+// went wrong when bugs are found, if they look at the Valgrind stack trace.
+
+BC_NORETURN void
+bcl_invalidGeneration(void);
+
+BC_NORETURN void
+bcl_nonexistentNum(void);
+
+BC_NORETURN void
+bcl_numIdxOutOfRange(void);
+
+#else // BC_ENABLE_MEMCHECK
+
+/**
+ * A typedef for non-Valgrind builds.
+ */
+typedef BcNum BclNum;
+
+#define BCL_NO_GEN(n) ((n).i)
+#define BCL_NUM(c, n) ((BclNum*) bc_vec_item(&(c)->nums, (n).i))
+#define BCL_CLEAR_GEN(n) ((void) (n))
+
+#define BCL_CHECK_NUM_GEN(c, bn)
+#define BCL_CHECK_NUM_VALID(c, n)
+
+#define BCL_NUM_ARRAY(bn) ((bn)->num)
+#define BCL_NUM_ARRAY_NP(bn) ((bn).num)
+
+#define BCL_NUM_NUM(bn) (bn)
+#define BCL_NUM_NUM_NP(bn) (&(bn))
+
+#endif // BC_ENABLE_MEMCHECK
+
/**
* A header that sets a jump.
* @param vm The thread data.
@@ -88,19 +227,19 @@
* idx.
* @param c The context.
* @param e The error.
- * @param n The number.
+ * @param bn The number.
* @param idx The idx to set as the return value.
*/
-#define BC_MAYBE_SETUP(c, e, n, idx) \
- do \
- { \
- if (BC_ERR((e) != BCL_ERROR_NONE)) \
- { \
- if ((n).num != NULL) bc_num_free(&(n)); \
- idx.i = 0 - (size_t) (e); \
- } \
- else idx = bcl_num_insert(c, &(n)); \
- } \
+#define BC_MAYBE_SETUP(c, e, bn, idx) \
+ do \
+ { \
+ if (BC_ERR((e) != BCL_ERROR_NONE)) \
+ { \
+ if (BCL_NUM_ARRAY_NP(bn) != NULL) bc_num_free(BCL_NUM_NUM_NP(bn)); \
+ idx.i = 0 - (size_t) (e); \
+ } \
+ else idx = bcl_num_insert(c, &(bn)); \
+ } \
while (0)
/**
@@ -108,17 +247,17 @@
* is bad.
* @param c The context.
*/
-#define BC_CHECK_CTXT(vm, c) \
- do \
- { \
- c = bcl_contextHelper(vm); \
- if (BC_ERR(c == NULL)) \
- { \
- BclNumber n_num; \
- n_num.i = 0 - (size_t) BCL_ERROR_INVALID_CONTEXT; \
- return n_num; \
- } \
- } \
+#define BC_CHECK_CTXT(vm, c) \
+ do \
+ { \
+ c = bcl_contextHelper(vm); \
+ if (BC_ERR(c == NULL)) \
+ { \
+ BclNumber n_num_; \
+ n_num_.i = 0 - (size_t) BCL_ERROR_INVALID_CONTEXT; \
+ return n_num_; \
+ } \
+ } \
while (0)
/**
@@ -157,16 +296,18 @@
#define BC_CHECK_NUM(c, n) \
do \
{ \
- if (BC_ERR((n).i >= (c)->nums.len)) \
+ size_t no_gen_ = BCL_NO_GEN(n); \
+ if (BC_ERR(no_gen_ >= (c)->nums.len)) \
{ \
if ((n).i > 0 - (size_t) BCL_ERROR_NELEMS) return (n); \
else \
{ \
- BclNumber n_num; \
- n_num.i = 0 - (size_t) BCL_ERROR_INVALID_NUM; \
- return n_num; \
+ BclNumber n_num_; \
+ n_num_.i = 0 - (size_t) BCL_ERROR_INVALID_NUM; \
+ return n_num_; \
} \
} \
+ BCL_CHECK_NUM_GEN(c, n); \
} \
while (0)
@@ -181,7 +322,8 @@
*** 6729 LINES SKIPPED ***