aboutsummaryrefslogtreecommitdiff
path: root/contrib/bc/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bc/scripts')
-rwxr-xr-xcontrib/bc/scripts/exec-install.sh17
-rwxr-xr-xcontrib/bc/scripts/format.sh53
-rwxr-xr-xcontrib/bc/scripts/functions.sh175
-rwxr-xr-xcontrib/bc/scripts/karatsuba.py9
-rwxr-xr-xcontrib/bc/scripts/link.sh7
-rwxr-xr-xcontrib/bc/scripts/lint.sh66
-rwxr-xr-xcontrib/bc/scripts/locale_install.sh16
-rwxr-xr-xcontrib/bc/scripts/locale_uninstall.sh2
-rwxr-xr-xcontrib/bc/scripts/safe-install.sh12
-rw-r--r--contrib/bc/scripts/sqrt_frac_guess.bc126
-rw-r--r--contrib/bc/scripts/sqrt_int_guess.bc94
-rw-r--r--contrib/bc/scripts/sqrt_random.bc129
-rwxr-xr-xcontrib/bc/scripts/sqrt_random.sh77
13 files changed, 762 insertions, 21 deletions
diff --git a/contrib/bc/scripts/exec-install.sh b/contrib/bc/scripts/exec-install.sh
index 25d56c6fc688..8180b29c9997 100755
--- a/contrib/bc/scripts/exec-install.sh
+++ b/contrib/bc/scripts/exec-install.sh
@@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
-# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -29,7 +29,7 @@
# Print usage and exit with an error.
usage() {
- printf "usage: %s install_dir exec_suffix\n" "$0" 1>&2
+ printf "usage: %s install_dir exec_suffix [bindir]\n" "$0" 1>&2
exit 1
}
@@ -49,12 +49,23 @@ shift
exec_suffix="$1"
shift
-bindir="$scriptdir/../bin"
+if [ "$#" -gt 0 ]; then
+ bindir="$1"
+ shift
+else
+ bindir="$scriptdir/../bin"
+fi
# Install or symlink, depending on the type of file. If it's a file, install it.
# If it's a symlink, create an equivalent in the install directory.
for exe in $bindir/*; do
+ # Skip any directories in case the bin/ directory is also used as the
+ # prefix.
+ if [ -d "$exe" ]; then
+ continue
+ fi
+
base=$(basename "$exe")
if [ -L "$exe" ]; then
diff --git a/contrib/bc/scripts/format.sh b/contrib/bc/scripts/format.sh
new file mode 100755
index 000000000000..dd227555b0fe
--- /dev/null
+++ b/contrib/bc/scripts/format.sh
@@ -0,0 +1,53 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+scriptdir=$(dirname "$0")
+
+. "$scriptdir/functions.sh"
+
+cd "$scriptdir/.."
+
+if [ "$#" -gt 0 ]; then
+ files="$@"
+else
+ files=$(find "." -name "*.c" -or -name "*.h")
+fi
+
+for f in $files; do
+
+ case "$f" in
+ *scripts/ministat.c) continue ;;
+ esac
+
+ clang-format -i --style=file "$f"
+ sed -i 's|^#else //|#else //|g' "$f"
+
+done
+
+sed -i 's|^ // clang-format on| // clang-format on|g' src/program.c
diff --git a/contrib/bc/scripts/functions.sh b/contrib/bc/scripts/functions.sh
index 65ec0a1167fe..8ae765859e51 100755
--- a/contrib/bc/scripts/functions.sh
+++ b/contrib/bc/scripts/functions.sh
@@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
-# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -71,6 +71,88 @@ err_exit() {
exit "$2"
}
+# Function for checking the "d"/"dir" argument of scripts. This function expects
+# a usage() function to exist in the caller.
+# @param 1 The argument to check.
+check_d_arg() {
+
+ if [ "$#" -ne 1 ]; then
+ printf 'Invalid number of args to check_d_arg\n'
+ exit 1
+ fi
+
+ _check_d_arg_arg="$1"
+ shift
+
+ if [ "$_check_d_arg_arg" != "bc" ] && [ "$_check_d_arg_arg" != "dc" ]; then
+ _check_d_arg_msg=$(printf 'Invalid d arg: %s\nMust be either "bc" or "dc".\n\n' \
+ "$_check_d_arg_arg")
+ usage "$_check_d_arg_msg"
+ fi
+}
+
+# Function for checking the boolean arguments of scripts. This function expects
+# a usage() function to exist in the caller.
+# @param 1 The argument to check.
+check_bool_arg() {
+
+ if [ "$#" -ne 1 ]; then
+ printf 'Invalid number of args to check_bool_arg\n'
+ exit 1
+ fi
+
+ _check_bool_arg_arg="$1"
+ shift
+
+ if [ "$_check_bool_arg_arg" != "0" ] && [ "$_check_bool_arg_arg" != "1" ]; then
+ _check_bool_arg_msg=$(printf 'Invalid bool arg: %s\nMust be either "0" or "1".\n\n' \
+ "$_check_bool_arg_arg")
+ usage "$_check_bool_arg_msg"
+ fi
+}
+
+# Function for checking the executable arguments of scripts. This function
+# expects a usage() function to exist in the caller.
+# @param 1 The argument to check.
+check_exec_arg() {
+
+ if [ "$#" -ne 1 ]; then
+ printf 'Invalid number of args to check_exec_arg\n'
+ exit 1
+ fi
+
+ _check_exec_arg_arg="$1"
+ shift
+
+ if [ ! -x "$_check_exec_arg_arg" ]; then
+ if ! command -v "$_check_exec_arg_arg" >/dev/null 2>&1; then
+ _check_exec_arg_msg=$(printf 'Invalid exec arg: %s\nMust be an executable file.\n\n' \
+ "$_check_exec_arg_arg")
+ usage "$_check_exec_arg_msg"
+ fi
+ fi
+}
+
+# Function for checking the file arguments of scripts. This function expects a
+# usage() function to exist in the caller.
+# @param 1 The argument to check.
+check_file_arg() {
+
+ if [ "$#" -ne 1 ]; then
+ printf 'Invalid number of args to check_file_arg\n'
+ exit 1
+ fi
+
+ _check_file_arg_arg="$1"
+ shift
+
+ if [ ! -f "$_check_file_arg_arg" ]; then
+ _check_file_arg_msg=$(printf 'Invalid file arg: %s\nMust be a file.\n\n' \
+ "$_check_file_arg_arg")
+ usage "$_check_file_arg_msg"
+ fi
+}
+
# Check the return code on a test and exit with a fail if it's non-zero.
# @param d The calculator under test.
# @param err The return code.
@@ -326,3 +408,94 @@ gen_nlspath() {
# Return the result.
printf '%s' "$_gen_nlspath_nlspath"
}
+
+ALL=0
+NOSKIP=1
+SKIP=2
+
+# Filters text out of a file according to the build type.
+# @param in File to filter.
+# @param out File to write the filtered output to.
+# @param type Build type.
+filter_text() {
+
+ _filter_text_in="$1"
+ shift
+
+ _filter_text_out="$1"
+ shift
+
+ _filter_text_buildtype="$1"
+ shift
+
+ # Set up some local variables.
+ _filter_text_status="$ALL"
+ _filter_text_last_line=""
+
+ # We need to set IFS, so we store it here for restoration later.
+ _filter_text_ifs="$IFS"
+
+ # Remove the file- that will be generated.
+ rm -rf "$_filter_text_out"
+
+ # Here is the magic. This loop reads the template line-by-line, and based on
+ # _filter_text_status, either prints it to the markdown manual or not.
+ #
+ # Here is how the template is set up: it is a normal markdown file except
+ # that there are sections surrounded tags that look like this:
+ #
+ # {{ <build_type_list> }}
+ # ...
+ # {{ end }}
+ #
+ # Those tags mean that whatever build types are found in the
+ # <build_type_list> get to keep that section. Otherwise, skip.
+ #
+ # Obviously, the tag itself and its end are not printed to the markdown
+ # manual.
+ while IFS= read -r _filter_text_line; do
+
+ # If we have found an end, reset the status.
+ if [ "$_filter_text_line" = "{{ end }}" ]; then
+
+ # Some error checking. This helps when editing the templates.
+ if [ "$_filter_text_status" -eq "$ALL" ]; then
+ err_exit "{{ end }} tag without corresponding start tag" 2
+ fi
+
+ _filter_text_status="$ALL"
+
+ # We have found a tag that allows our build type to use it.
+ elif [ "${_filter_text_line#\{\{* $_filter_text_buildtype *\}\}}" != "$_filter_text_line" ]; then
+
+ # More error checking. We don't want tags nested.
+ if [ "$_filter_text_status" -ne "$ALL" ]; then
+ err_exit "start tag nested in start tag" 3
+ fi
+
+ _filter_text_status="$NOSKIP"
+
+ # We have found a tag that is *not* allowed for our build type.
+ elif [ "${_filter_text_line#\{\{*\}\}}" != "$_filter_text_line" ]; then
+
+ if [ "$_filter_text_status" -ne "$ALL" ]; then
+ err_exit "start tag nested in start tag" 3
+ fi
+
+ _filter_text_status="$SKIP"
+
+ # This is for normal lines. If we are not skipping, print.
+ else
+ if [ "$_filter_text_status" -ne "$SKIP" ]; then
+ if [ "$_filter_text_line" != "$_filter_text_last_line" ]; then
+ printf '%s\n' "$_filter_text_line" >> "$_filter_text_out"
+ fi
+ _filter_text_last_line="$_filter_text_line"
+ fi
+ fi
+
+ done < "$_filter_text_in"
+
+ # Reset IFS.
+ IFS="$_filter_text_ifs"
+}
diff --git a/contrib/bc/scripts/karatsuba.py b/contrib/bc/scripts/karatsuba.py
index b8505186b526..9c94ffe448f7 100755
--- a/contrib/bc/scripts/karatsuba.py
+++ b/contrib/bc/scripts/karatsuba.py
@@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
-# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -49,9 +49,6 @@ testdir = os.path.dirname(script)
if testdir == "":
testdir = os.getcwd()
-# We want to be in the root directory.
-os.chdir(testdir + "/..")
-
print("\nWARNING: This script is for distro and package maintainers.")
print("It is for finding the optimal Karatsuba number.")
print("Though it only needs to be run once per release/platform,")
@@ -116,7 +113,7 @@ try:
except KeyError:
flags["CFLAGS"] = "-flto"
-p = run([ "./configure.sh", "-O3" ], flags)
+p = run([ "{}/../configure.sh".format(testdir), "-O3" ], flags)
if p.returncode != 0:
print("configure.sh returned an error ({}); exiting...".format(p.returncode))
sys.exit(p.returncode)
@@ -161,7 +158,7 @@ try:
# Configure and compile.
print("\nCompiling...\n")
- p = run([ "./configure.sh", "-O3", "-k{}".format(i) ], config_env)
+ p = run([ "{}/../configure.sh".format(testdir), "-O3", "-k{}".format(i) ], config_env)
if p.returncode != 0:
print("configure.sh returned an error ({}); exiting...".format(p.returncode))
diff --git a/contrib/bc/scripts/link.sh b/contrib/bc/scripts/link.sh
index f1c403d50dda..7d95f866e17b 100755
--- a/contrib/bc/scripts/link.sh
+++ b/contrib/bc/scripts/link.sh
@@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
-# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -32,6 +32,11 @@ usage() {
exit 1
}
+script="$0"
+scriptdir=$(dirname "$script")
+
+. "$scriptdir/functions.sh"
+
# Command-line processing.
test "$#" -gt 1 || usage
diff --git a/contrib/bc/scripts/lint.sh b/contrib/bc/scripts/lint.sh
new file mode 100755
index 000000000000..5a217204f8f5
--- /dev/null
+++ b/contrib/bc/scripts/lint.sh
@@ -0,0 +1,66 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+script="$0"
+scriptdir=$(dirname "$script")
+
+. "$scriptdir/functions.sh"
+
+cd "$scriptdir/.."
+
+if [ "$#" -gt 0 ]; then
+ files="$@"
+else
+ files=$(find "." -name "*.c" -or -name "*.h")
+fi
+
+for f in $files; do
+
+ case "$f" in
+ *scripts/ministat.c) continue ;;
+ esac
+
+ contents=$(clang-tidy --use-color -p ../build "$f" -- -I./include \
+ -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -D_BSD_SOURCE \
+ -D_GNU_SOURCE -D_DEFAULT_SOURCE 2>&1)
+
+ err="$?"
+
+ if [ ! -z "$contents" ] || [ "$err" -ne 0 ]; then
+
+ printf '%s\n' "$f"
+ printf '%s\n' "$contents"
+ printf '\n'
+
+ if [ "$err" -ne 0 ]; then
+ exit "$err"
+ fi
+ fi
+
+done
diff --git a/contrib/bc/scripts/locale_install.sh b/contrib/bc/scripts/locale_install.sh
index a67e6aa52970..3816f54ef495 100755
--- a/contrib/bc/scripts/locale_install.sh
+++ b/contrib/bc/scripts/locale_install.sh
@@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
-# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -28,6 +28,7 @@
#
# Just print the usage and exit with an error.
+# @param 1 A message to print.
usage() {
if [ $# -eq 1 ]; then
printf '%s\n' "$1"
@@ -183,13 +184,14 @@ all_locales=0
while getopts "l" opt; do
case "$opt" in
- l) all_locales=1 ; shift ;;
+ l) all_locales=1 ;;
?) usage "Invalid option: $opt" ;;
esac
done
+shift $(($OPTIND - 1))
-test "$#" -ge 2 || usage
+test "$#" -ge 2 || usage "Must have at least two arguments"
nlspath="$1"
shift
@@ -240,11 +242,15 @@ for file in $locales_dir/*.msg; do
continue
fi
+ printf 'Installing %s...' "$locale"
+
# Generate the proper location for the cat file.
loc=$(gen_nlspath "$destdir/$nlspath" "$locale" "$main_exec")
gencatfile "$loc" "$file"
+ printf 'done\n'
+
done
# Now that we have done the non-symlinks, it's time to do the symlinks. Think
@@ -275,6 +281,8 @@ for file in $locales_dir/*.msg; do
# Make sure to skip non-symlinks; they are already done.
if [ -L "$file" ]; then
+ printf 'Linking %s...' "$locale"
+
# This song and dance is because we want to generate relative symlinks.
# They take less space, but also, they are more resilient to being
# moved.
@@ -294,6 +302,8 @@ for file in $locales_dir/*.msg; do
# Finally, symlink to the install of the generated cat file that
# corresponds to the correct msg file.
ln -fs "$rel" "$loc"
+
+ printf 'done\n'
fi
done
diff --git a/contrib/bc/scripts/locale_uninstall.sh b/contrib/bc/scripts/locale_uninstall.sh
index 3e79e083b803..dfa3899db26b 100755
--- a/contrib/bc/scripts/locale_uninstall.sh
+++ b/contrib/bc/scripts/locale_uninstall.sh
@@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: BSD-2-Clause
#
-# Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
diff --git a/contrib/bc/scripts/safe-install.sh b/contrib/bc/scripts/safe-install.sh
index 041088386682..5774a17e20de 100755
--- a/contrib/bc/scripts/safe-install.sh
+++ b/contrib/bc/scripts/safe-install.sh
@@ -41,7 +41,7 @@ set -e
if test "$mkdirp" ; then
umask 022
-case "$2" in
+case "$dst" in
*/*) mkdir -p "${dst%/*}" ;;
esac
fi
@@ -51,15 +51,15 @@ trap 'rm -f "$tmp"' EXIT INT QUIT TERM HUP
umask 077
if test "$symlink" ; then
-ln -s "$1" "$tmp"
+ln -s "$src" "$tmp"
else
-cat < "$1" > "$tmp"
+cat < "$src" > "$tmp"
chmod "$mode" "$tmp"
fi
-mv -f "$tmp" "$2"
-test -d "$2" && {
-rm -f "$2/$tmp"
+mv -f "$tmp" "$dst"
+test -d "$dst" && {
+rm -f "$dst/$tmp"
printf "%s: %s is a directory\n" "$0" "$dst" 1>&2
exit 1
}
diff --git a/contrib/bc/scripts/sqrt_frac_guess.bc b/contrib/bc/scripts/sqrt_frac_guess.bc
new file mode 100644
index 000000000000..5938cfcc7cba
--- /dev/null
+++ b/contrib/bc/scripts/sqrt_frac_guess.bc
@@ -0,0 +1,126 @@
+#! /usr/bin/bc
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+scale = 20
+
+# Adjust this number to try ranges below different powers of 10.
+shift = 4
+
+# Adjust this to try extra digits. For example, a value of one means that one
+# digit is checked (such as 0.09 through 0.01), a value of two means that two
+# digits are checked (0.090 through 0.010), etc.
+max = shift + 2
+
+n = (9 >> shift)
+inc = (1 >> max)
+stop = (1 >> shift)
+
+# Uncomment this to test the high part of the ranges.
+#n += (1 - (1 >> max + 5)) >> shift
+
+for (i = n; i >= stop; i -= inc)
+{
+ # This is the lower limit.
+ t1 = sqrt(1/(3*i))
+
+ # Start with the inverse.
+ t2 = (1/i)
+
+ # And take half its length of course.
+ l = length(t2$)/2
+
+ temp = i
+ odd = 0
+
+ # We go by powers of 10 below, but there is a degenerate case: an exact
+ # power of 10, for which length() will return one digit more. So we check
+ # for that and fix it.
+ while (temp < 1)
+ {
+ temp <<= 1
+ odd = !odd
+ }
+
+ if (temp == 1)
+ {
+ odd = !odd
+ }
+
+ print "i: ", i, "\n"
+ print "t2: ", t2, "\n"
+ #print "l: ", l, "\n"
+ print "odd: ", odd, "\n"
+
+ if (odd)
+ {
+ # Limit between 6 and 7.5.
+ limit1 = 6.7 >> (l$ * 2 + 1)
+
+ # Limit between 1.5 and 1.83-ish.
+ limit2 = 1.7 >> (l$ * 2 + 1)
+ print "limit1: ", limit1, "\n"
+ print "limit2: ", limit2, "\n"
+
+ if (i >= limit1)
+ {
+ t2 = (t2 >> l$)
+ }
+ else if (i >= limit2)
+ {
+ t2 = (t2 >> l$) / 2
+ }
+ else
+ {
+ t2 = (t2 >> l$) / 4
+ }
+ }
+ else
+ {
+ # Limit between 2.4 and 3.
+ limit = 2.7 >> (l$ * 2)
+ print "limit: ", limit, "\n"
+
+ if (i >= limit)
+ {
+ t2 = (t2 >> l$) * 2
+ }
+ else
+ {
+ t2 = (t2 >> l$)
+ }
+ }
+ #t2 = 1
+ t3 = sqrt(5/(3*i))
+ good = (t1 < t2 && t2 < t3)
+
+ print t1, " < ", t2, " < ", t3, ": ", good, "\n\n"
+ if (!good) sqrt(-1)
+}
+
+halt
diff --git a/contrib/bc/scripts/sqrt_int_guess.bc b/contrib/bc/scripts/sqrt_int_guess.bc
new file mode 100644
index 000000000000..551a06eb2e6d
--- /dev/null
+++ b/contrib/bc/scripts/sqrt_int_guess.bc
@@ -0,0 +1,94 @@
+#! /usr/bin/bc -l
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+# Adjust this number to try ranges above different powers of 10.
+max = 0
+
+n = (1 << max)
+
+# Uncomment this to test the high part of the ranges.
+#n += (1 - (1 >> 10))
+
+n
+
+# Loop from the start number to the next power of 10.
+for (i = n; i < (n$ << 1); i += 1)
+{
+ # This is the lower limit.
+ t1 = sqrt(1/(3*i))
+
+ l = length(i$)/2
+
+ print "i: ", i, "\n"
+ #print "l: ", l, "\n"
+
+ if (l$ != l)
+ {
+ # Limit between 2.4 and 3.
+ limit = 2.7 << (l$ * 2)
+ #print "limit: ", limit, "\n"
+
+ if (i >= limit)
+ {
+ t2 = 1/(i >> (l$)) * 2
+ }
+ else
+ {
+ t2 = 1/(i >> (l$))
+ }
+ }
+ else
+ {
+ # Limit between 3.8-ish and 4.8
+ limit = 4.3 << (l$ * 2 - 1)
+ #print "limit: ", limit, "\n"
+
+ if (i >= limit)
+ {
+ t2 = 1/(i >> (l$ - 1)) * 8
+ }
+ else
+ {
+ t2 = 1/(i >> (l$ - 1)) * 4
+ }
+ }
+
+ # This is the upper limit.
+ t3 = sqrt(5/(3*i))
+
+ # This is true when the guess is in between the limits.
+ good = (t1 < t2 && t2 < t3)
+
+ print t1, " < ", t2, " < ", t3, ": ", good, "\n"
+
+ # Error if we have a problem.
+ if (!good) sqrt(-1)
+}
+
+halt
diff --git a/contrib/bc/scripts/sqrt_random.bc b/contrib/bc/scripts/sqrt_random.bc
new file mode 100644
index 000000000000..ff08348f4977
--- /dev/null
+++ b/contrib/bc/scripts/sqrt_random.bc
@@ -0,0 +1,129 @@
+#! /usr/bin/bc
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+scale = 0
+
+bits = rand()
+
+# This extracts a bit and takes it out of the original value.
+#
+# Here, I am getting a bit to say whether we should have a value that is less
+# than 1.
+bits = divmod(bits, 2, negpow[])
+
+# Get a bit that will say whether the value should be an exact square.
+bits = divmod(bits, 2, square[])
+
+# See below. This is to help bias toward small numbers.
+pow = 4
+
+# I want to bias toward small numbers, so let's give a 50 percent chance to
+# values below 16 or so.
+bits = divmod(bits, 2, small[])
+
+# Let's keep raising the power limit by 2^4 when the bit is zero.
+while (!small[0])
+{
+ pow += 4
+ bits = divmod(bits, 2, small[])
+}
+
+limit = 2^pow
+
+# Okay, this is the starting number.
+num = irand(limit) + 1
+
+# Figure out if we should have (more) fractional digits.
+bits = divmod(bits, 2, extra_digits[])
+
+if (square[0])
+{
+ # Okay, I lied. If we need a perfect square, square now.
+ num *= num
+
+ # If we need extra digits, we need to multiply by an even power of 10.
+ if (extra_digits[0])
+ {
+ extra = (irand(8) + 1) * 2
+ }
+ else
+ {
+ extra = 0
+ }
+
+ # If we need a number less than 1, just take the inverse, which will still
+ # be a perfect square.
+ if (negpow[0])
+ {
+ scale = length(num) + 5
+ num = 1/num
+ scale = 0
+
+ num >>= extra
+ }
+ else
+ {
+ num <<= extra
+ }
+}
+else
+{
+ # Get this for later.
+ l = length(num)
+
+ # If we need extra digits.
+ if (extra_digits[0])
+ {
+ # Add up to 32 decimal places.
+ num += frand(irand(32) + 1)
+ }
+
+ # If we need a value less than 1...
+ if (negpow[0])
+ {
+ # Move right until the number is
+ num >>= l
+ }
+}
+
+bits = divmod(bits, 2, zero_scale[])
+
+# Do we want a zero scale?
+if (zero_scale[0])
+{
+ print "scale = 0\n"
+}
+else
+{
+ print "scale = 20\n"
+}
+
+print "sqrt(", num, ")\n"
+
+halt
diff --git a/contrib/bc/scripts/sqrt_random.sh b/contrib/bc/scripts/sqrt_random.sh
new file mode 100755
index 000000000000..694c72003192
--- /dev/null
+++ b/contrib/bc/scripts/sqrt_random.sh
@@ -0,0 +1,77 @@
+#! /bin/sh
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2018-2023 Gavin D. Howard and contributors.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+scriptdir=$(dirname "$0")
+
+gnu=/usr/bin/bc
+gdh=/usr/local/bin/bc
+
+if [ "$#" -lt 1 ]; then
+ printf 'err: must provide path to new bc\n'
+ exit 1
+fi
+
+new="$1"
+shift
+
+unset BC_LINE_LENGTH && unset BC_ENV_ARGS
+
+gdh_fail_file="sqrt_fails.bc"
+new_fail_file="new_sqrt_fails.bc"
+
+rm -rf "$gdh_fail_file"
+rm -rf "$new_fail_file"
+
+while [ true ]; do
+
+ tst=$("$gdh" -l "$scriptdir/sqrt_random.bc")
+ err=$?
+
+ if [ "$err" -ne 0 ]; then
+ printf 'err: failed to create test\n'
+ exit 2
+ fi
+
+ good=$(printf '%s\n' "$tst" | "$gnu" -l)
+
+ gdh_out=$(printf '%s\n' "$tst" | "$gdh" -l)
+ new_out=$(printf '%s\n' "$tst" | "$new" -l)
+
+ gdh_good=$(printf '%s == %s\n' "$good" "$gdh_out" | "$gnu")
+ new_good=$(printf '%s == %s\n' "$good" "$new_out" | "$gnu")
+
+ if [ "$gdh_good" -eq 0 ]; then
+ printf '%s\n' "$tst" >> "$gdh_fail_file"
+ fi
+
+ if [ "$new_good" -eq 0 ]; then
+ printf '%s\n' "$tst" >> "$new_fail_file"
+ fi
+
+done