git: 46494d4edf98 - stable/13 - vendor/bc: import version 6.3.1

From: Stefan Eßer <se_at_FreeBSD.org>
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 ***