diff options
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/afl.py | 245 | ||||
| -rwxr-xr-x | scripts/alloc.sh | 84 | ||||
| -rwxr-xr-x | scripts/benchmark.sh | 159 | ||||
| -rw-r--r-- | scripts/bitfuncgen.c | 240 | ||||
| -rwxr-xr-x | scripts/fuzz_prep.sh | 81 | ||||
| -rwxr-xr-x | scripts/manpage.sh | 175 | ||||
| -rw-r--r-- | scripts/ministat.c | 675 | ||||
| -rwxr-xr-x | scripts/package.sh | 248 | ||||
| -rwxr-xr-x | scripts/radamsa.sh | 133 | ||||
| -rw-r--r-- | scripts/radamsa.txt | 17 | ||||
| -rwxr-xr-x | scripts/randmath.py | 421 | ||||
| -rwxr-xr-x | scripts/release.sh | 810 | ||||
| -rw-r--r-- | scripts/release_settings.txt | 16 | ||||
| -rwxr-xr-x | scripts/test_settings.sh | 77 | ||||
| -rw-r--r-- | scripts/test_settings.txt | 93 |
15 files changed, 3474 insertions, 0 deletions
diff --git a/scripts/afl.py b/scripts/afl.py new file mode 100755 index 000000000000..c4312ce84f83 --- /dev/null +++ b/scripts/afl.py @@ -0,0 +1,245 @@ +#! /usr/bin/python3 -B +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +import os +import sys +import shutil +import subprocess + + +# Print the usage and exit with an error. +def usage(): + print("usage: {} [--asan] dir [results_dir [exe options...]]".format(script)) + print(" The valid values for dir are: 'bc1', 'bc2', 'bc3', and 'dc'.") + sys.exit(1) + + +# Check for a crash. +# @param exebase The calculator that crashed. +# @param out The file to copy the crash file to. +# @param error The error code (negative). +# @param file The crash file. +# @param type The type of run that caused the crash. This is just a string +# that would make sense to the user. +# @param test The contents of the crash file, or which line caused the crash +# for a run through stdin. +def check_crash(exebase, out, error, file, type, test): + if error < 0: + print("\n{} crashed ({}) on {}:\n".format(exebase, -error, type)) + print(" {}".format(test)) + print("\nCopying to \"{}\"".format(out)) + shutil.copy2(file, out) + print("\nexiting...") + sys.exit(error) + + +# Runs a test. This function is used to ensure that if a test times out, it is +# discarded. Otherwise, some tests result in incredibly long runtimes. We need +# to ignore those. +# +# @param cmd The command to run. +# @param exebase The calculator to test. +# @param tout The timeout to use. +# @param indata The data to push through stdin for the test. +# @param out The file to copy the test file to if it causes a crash. +# @param file The test file. +# @param type The type of test. This is just a string that would make sense +# to the user. +# @param test The test. It could be an entire file, or just one line. +# @param environ The environment to run the command under. +def run_test(cmd, exebase, tout, indata, out, file, type, test, environ=None): + try: + p = subprocess.run(cmd, timeout=tout, input=indata, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, env=environ) + check_crash(exebase, out, p.returncode, file, type, test) + except subprocess.TimeoutExpired: + print("\n {} timed out. Continuing...\n".format(exebase)) + + +# Creates and runs a test. This basically just takes a file, runs it through the +# appropriate calculator as a whole file, then runs it through the calculator +# using stdin. +# @param file The file to test. +# @param tout The timeout to use. +# @param environ The environment to run under. +def create_test(file, tout, environ=None): + + print(" {}".format(file)) + + base = os.path.basename(file) + + if base == "README.txt": + return + + with open(file, "rb") as f: + lines = f.readlines() + + print(" Running whole file...") + + run_test(exe + [ file ], exebase, tout, halt.encode(), out, file, "file", file, environ) + + print(" Running file through stdin...") + + with open(file, "rb") as f: + content = f.read() + + run_test(exe, exebase, tout, content, out, file, + "running {} through stdin".format(file), file, environ) + + +# Get the children of a directory. +# @param dir The directory to get the children of. +# @param get_files True if files should be gotten, false if directories should +# be gotten. +def get_children(dir, get_files): + dirs = [] + with os.scandir(dir) as it: + for entry in it: + if not entry.name.startswith('.') and \ + ((entry.is_dir() and not get_files) or \ + (entry.is_file() and get_files)): + dirs.append(entry.name) + dirs.sort() + return dirs + + +# Returns the correct executable name for the directory under test. +# @param d The directory under test. +def exe_name(d): + return "bc" if d == "bc1" or d == "bc2" or d == "bc3" else "dc" + + +# Housekeeping. +script = sys.argv[0] +scriptdir = os.path.dirname(script) + +# Must run this script alone. +if __name__ != "__main__": + usage() + +timeout = 2.5 + +if len(sys.argv) < 2: + usage() + +idx = 1 + +exedir = sys.argv[idx] + +asan = (exedir == "--asan") + +# We could possibly run under ASan. See later for what that means. +if asan: + idx += 1 + if len(sys.argv) < idx + 1: + usage() + exedir = sys.argv[idx] + +print("exedir: {}".format(exedir)) + +# Grab the correct directory of AFL++ results. +if len(sys.argv) >= idx + 2: + resultsdir = sys.argv[idx + 1] +else: + if exedir == "bc1": + resultsdir = scriptdir + "/../tests/fuzzing/bc_outputs1" + elif exedir == "bc2": + resultsdir = scriptdir + "/../tests/fuzzing/bc_outputs2" + elif exedir == "bc3": + resultsdir = scriptdir + "/../tests/fuzzing/bc_outputs3" + elif exedir == "dc": + resultsdir = scriptdir + "/../tests/fuzzing/dc_outputs" + else: + raise ValueError("exedir must be either bc1, bc2, bc3, or dc"); + +print("resultsdir: {}".format(resultsdir)) + +# More command-line processing. +if len(sys.argv) >= idx + 3: + exe = sys.argv[idx + 2] +else: + exe = scriptdir + "/../bin/" + exe_name(exedir) + +exebase = os.path.basename(exe) + + +# Use the correct options. +if exebase == "bc": + halt = "halt\n" + options = "-lq" + seed = ["-e", "seed = 1280937142.20981723890730892738902938071028973408912703984712093", "-f-" ] +else: + halt = "q\n" + options = "-x" + seed = ["-e", "1280937142.20981723890730892738902938071028973408912703984712093j", "-f-" ] + +# More command-line processing. +if len(sys.argv) >= idx + 4: + exe = [ exe, sys.argv[idx + 3:], options ] + seed +else: + exe = [ exe, options ] + seed +for i in range(4, len(sys.argv)): + exe.append(sys.argv[i]) + +out = scriptdir + "/../.test.txt" + +print(os.path.realpath(os.getcwd())) + +dirs = get_children(resultsdir, False) + +# Set the correct ASAN_OPTIONS. +if asan: + env = os.environ.copy() + env['ASAN_OPTIONS'] = 'abort_on_error=1:allocator_may_return_null=1' + +for d in dirs: + + d = resultsdir + "/" + d + + print(d) + + # Check the crash files. + files = get_children(d + "/crashes/", True) + + for file in files: + file = d + "/crashes/" + file + create_test(file, timeout) + + # If we are running under ASan, we want to check all files. Otherwise, skip. + if not asan: + continue + + # Check all of the test cases found by AFL++. + files = get_children(d + "/queue/", True) + + for file in files: + file = d + "/queue/" + file + create_test(file, timeout * 2, env) + +print("Done") diff --git a/scripts/alloc.sh b/scripts/alloc.sh new file mode 100755 index 000000000000..c5c46febe0b3 --- /dev/null +++ b/scripts/alloc.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +# This script is only really useful for running on Linux. It tests the code to +# free temps in order to make an allocation work. In order to see it work, I +# suggest adding code after the following line in src/vm.c: +# +# if (BC_ERR(ptr == NULL)) bc_vm_fatalError(BC_ERR_FATAL_ALLOC_ERR); +# +# The code you should add is the following: +# +# bc_file_printf(&vm.ferr, "If you see this, the code worked.\n"); +# bc_file_flush(&vm.ferr, bc_flush_none); +# +# If you do not see the that message printed, the code did not work. Or, in the +# case of some allocators, like jemalloc, the allocator just isn't great with +# turning a bunch of small allocations into a bigger allocation, + +script="$0" +scriptdir=$(dirname "$script") + +export LANG=C + +virtlimit=1000000 + +ulimit -v $virtlimit + +# This script is designed to allocate lots of memory with a lot of caching of +# numbers (the function f() specifically). Then, it's designed allocate one +# large number and grow it until allocation failure (the function g()). +"$scriptdir/../bin/bc" <<*EOF + +define f(i, n) { + if (n == 0) return i; + return f(i + 1, n - 1) +} + +define g(n) { + t = (10^9)^(2^24) + while (n) { + n *= t + print "success\n" + } +} + +iterations=2000000 + +for (l=0; l < 100; l++) { + iterations + j = f(0, iterations$) + iterations += 100000 + print "here\n" + n=10^235929600 + g(n) + print "success\n" + n=0 +} +*EOF diff --git a/scripts/benchmark.sh b/scripts/benchmark.sh new file mode 100755 index 000000000000..35f92452ce78 --- /dev/null +++ b/scripts/benchmark.sh @@ -0,0 +1,159 @@ +#! /bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +# This script depends on the GNU time utility, but I am okay with that because +# this script is only for maintainers. + +# Just print the usage and exit with an error. +usage() { + printf 'usage: %s [-n<runs>] [-p<pause>] dir benchmark...\n' "$0" 1>&2 + printf ' -n runs is how many runs to run the benchmark, default 10.\n' + printf ' -p pause is how many seconds to pause before running the benchmarks.\n' + printf '\n' + printf 'The fields are put in this order:\n' + printf '1. Elapsed Time\n' + printf '2. System Time\n' + printf '3. User Time\n' + printf '4. Max RSS\n' + printf '5. Average RSS\n' + printf '6. Average Total Memory Use\n' + printf '7. Average Unshared Data\n' + printf '8. Average Unshared Stack\n' + printf '9. Average Shared Text\n' + printf '10. Major Page Faults\n' + printf '11. Minor Page Faults\n' + printf '12. Swaps\n' + printf '13. Involuntary Context Switches\n' + printf '14. Voluntary Context Switches\n' + printf '15. Inputs\n' + printf '16. Outputs\n' + printf '17. Signals Delivered\n' + exit 1 +} + +script="$0" +scriptdir=$(dirname "$script") + +runs=10 +pause=0 + +# Process command-line arguments. +while getopts "n:p:" opt; do + + case "$opt" in + n) runs="$OPTARG" ;; + p) pause="$OPTARG" ;; + ?) usage "Invalid option: $opt" ;; + esac + +done + +while [ "$#" -gt 0 ] && [ "$OPTIND" -gt 1 ]; do + + OPTIND=$(bin/bc -e "$OPTIND - 1") + shift + +done + +if [ "$#" -lt 2 ]; then + usage +fi + +cd "$scriptdir/.." + +d="$1" +shift + +benchmarks="" + +# Create the list of benchmarks from the arguments. +while [ "$#" -gt 0 ]; do + + if [ "$benchmarks" = "" ]; then + benchmarks="$1" + else + benchmarks="$benchmarks $1" + fi + + shift +done + +files="" + +# Create the list of files from the benchmarks. +for b in $benchmarks; do + + f=$(printf "benchmarks/%s/%s.txt" "$d" "$b") + + if [ "$files" = "" ]; then + files="$f" + else + files="$files $f" + fi + +done + +if [ "$d" = "bc" ]; then + opts="-lq" + halt="halt" +else + opts="-x" + halt="q" +fi + +# Generate all of the benchmarks. +for b in $benchmarks; do + + if [ ! -f "./benchmarks/$d/$b.txt" ]; then + printf 'Benchmarking generation of benchmarks/%s/%s.txt...\n' "$d" "$b" >&2 + printf '%s\n' "$halt" | /usr/bin/time -v bin/$d $opts "./benchmarks/$d/$b.$d" \ + > "./benchmarks/$d/$b.txt" + fi +done + +# We use this format to make things easier to use with ministat. +format="%e %S %U %M %t %K %D %p %X %F %R %W %c %w %I %O %k" + +printf 'Benchmarking %s...\n' "$files" >&2 + +if [ "$pause" -gt 0 ]; then + sleep "$pause" +fi + +i=0 + +# Run the benchmarks as many times as told to. +while [ "$i" -lt "$runs" ]; do + + printf '%s\n' "$halt" | /usr/bin/time -f "$format" bin/$d $opts $files 2>&1 > /dev/null + + # Might as well use the existing bc. + i=$(printf '%s + 1\n' "$i" | bin/bc) + +done diff --git a/scripts/bitfuncgen.c b/scripts/bitfuncgen.c new file mode 100644 index 000000000000..8fae531b9286 --- /dev/null +++ b/scripts/bitfuncgen.c @@ -0,0 +1,240 @@ +/* + * ***************************************************************************** + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2018-2021 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. + * + * ***************************************************************************** + * + * A generator for bitwise operations test. + * + */ + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> + +#define NTESTS (100) + +/** + * Abort with an error message. + * @param msg The error message. + */ +void err(const char *msg) { + fprintf(stderr, "%s\n", msg); + abort(); +} + +uint64_t rev(uint64_t a, size_t bits) { + + size_t i; + uint64_t res = 0; + + for (i = 0; i < bits; ++i) { + res <<= 1; + res |= a & 1; + a >>= 1; + } + + return res; +} + +uint64_t mod(uint64_t a, size_t bits) { + + uint64_t mod; + + if (bits < 64) mod = (uint64_t) ((1ULL << bits) - 1); + else mod = UINT64_MAX; + + return a & mod; +} + +uint64_t rol(uint64_t a, uint64_t p, size_t bits) { + + uint64_t res; + + assert(bits <= 64); + + p %= bits; + + if (!p) return a; + + res = (a << p) | (a >> (bits - p)); + + return mod(res, bits); +} + +uint64_t ror(uint64_t a, uint64_t p, size_t bits) { + + uint64_t res; + + assert(bits <= 64); + + p %= bits; + + if (!p) return a; + + res = (a << (bits - p)) | (a >> p); + + return mod(res, bits); +} + +int main(void) { + + uint64_t a = 0, b = 0, t; + size_t i; + + // We attempt to open this or /dev/random to get random data. + int fd = open("/dev/urandom", O_RDONLY); + + if (fd < 0) { + + fd = open("/dev/random", O_RDONLY); + + if (fd < 0) err("cannot open a random number generator"); + } + + // Generate NTESTS tests. + for (i = 0; i < NTESTS; ++i) { + + ssize_t nread; + + // Generate random data for the first operand. + nread = read(fd, (char*) &a, sizeof(uint64_t)); + if (nread != sizeof(uint64_t)) err("I/O error"); + + // Generate random data for the second operand. + nread = read(fd, (char*) &b, sizeof(uint64_t)); + if (nread != sizeof(uint64_t)) err("I/O error"); + + // Output the tests to stdout. + printf("band(%lu, %lu)\n", a, b); + printf("bor(%lu, %lu)\n", a, b); + printf("bxor(%lu, %lu)\n", a, b); + printf("bshl(%lu, %lu)\n", mod(a, 32), mod(b, 5)); + printf("bshr(%lu, %lu)\n", mod(a, 32), mod(b, 5)); + printf("bshl(%lu, %lu)\n", mod(b, 32), mod(a, 5)); + printf("bshr(%lu, %lu)\n", mod(b, 32), mod(a, 5)); + printf("bnot8(%lu)\nbnot8(%lu)\n", a, mod(a, 8)); + printf("bnot16(%lu)\nbnot16(%lu)\n", a, mod(a, 16)); + printf("bnot32(%lu)\nbnot32(%lu)\n", a, mod(a, 32)); + printf("bnot64(%lu)\n", a); + printf("brev8(%lu)\nbrev8(%lu)\n", a, mod(a, 8)); + printf("brev16(%lu)\nbrev16(%lu)\n", a, mod(a, 16)); + printf("brev32(%lu)\nbrev32(%lu)\n", a, mod(a, 32)); + printf("brev64(%lu)\n", a); + printf("brol8(%lu, %lu)\n", a, b); + printf("brol8(%lu, %lu)\n", mod(a, 8), b); + printf("brol8(%lu, %lu)\n", a, mod(b, 8)); + printf("brol8(%lu, %lu)\n", mod(a, 8), mod(b, 8)); + printf("brol16(%lu, %lu)\n", a, b); + printf("brol16(%lu, %lu)\n", mod(a, 16), b); + printf("brol16(%lu, %lu)\n", a, mod(b, 16)); + printf("brol16(%lu, %lu)\n", mod(a, 16), mod(b, 16)); + printf("brol32(%lu, %lu)\n", a, b); + printf("brol32(%lu, %lu)\n", mod(a, 32), b); + printf("brol32(%lu, %lu)\n", a, mod(b, 32)); + printf("brol32(%lu, %lu)\n", mod(a, 32), mod(b, 32)); + printf("brol64(%lu, %lu)\n", a, b); + printf("bror8(%lu, %lu)\n", a, b); + printf("bror8(%lu, %lu)\n", mod(a, 8), b); + printf("bror8(%lu, %lu)\n", a, mod(b, 8)); + printf("bror8(%lu, %lu)\n", mod(a, 8), mod(b, 8)); + printf("bror16(%lu, %lu)\n", a, b); + printf("bror16(%lu, %lu)\n", mod(a, 16), b); + printf("bror16(%lu, %lu)\n", a, mod(b, 16)); + printf("bror16(%lu, %lu)\n", mod(a, 16), mod(b, 16)); + printf("bror32(%lu, %lu)\n", a, b); + printf("bror32(%lu, %lu)\n", mod(a, 32), b); + printf("bror32(%lu, %lu)\n", a, mod(b, 32)); + printf("bror32(%lu, %lu)\n", mod(a, 32), mod(b, 32)); + printf("bror64(%lu, %lu)\n", a, b); + printf("bmod8(%lu)\nbmod8(%lu)\n", a, mod(a, 8)); + printf("bmod16(%lu)\nbmod16(%lu)\n", a, mod(a, 16)); + printf("bmod32(%lu)\nbmod32(%lu)\n", a, mod(a, 32)); + printf("bmod64(%lu)\n", a); + + // Output the results to stderr. + fprintf(stderr, "%lu\n", a & b); + fprintf(stderr, "%lu\n", a | b); + fprintf(stderr, "%lu\n", a ^ b); + fprintf(stderr, "%lu\n", mod(a, 32) << mod(b, 5)); + fprintf(stderr, "%lu\n", mod(a, 32) >> mod(b, 5)); + fprintf(stderr, "%lu\n", mod(b, 32) << mod(a, 5)); + fprintf(stderr, "%lu\n", mod(b, 32) >> mod(a, 5)); + t = mod(~a, 8); + fprintf(stderr, "%lu\n%lu\n", t, t); + t = mod(~a, 16); + fprintf(stderr, "%lu\n%lu\n", t, t); + t = mod(~a, 32); + fprintf(stderr, "%lu\n%lu\n", t, t); + fprintf(stderr, "%lu\n", ~a); + t = rev(a, 8); + fprintf(stderr, "%lu\n%lu\n", t, t); + t = rev(a, 16); + fprintf(stderr, "%lu\n%lu\n", t, t); + t = rev(a, 32); + fprintf(stderr, "%lu\n%lu\n", t, t); + t = rev(a, 64); + fprintf(stderr, "%lu\n", t); + fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8)); + fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8)); + fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8)); + fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8)); + fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16)); + fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16)); + fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16)); + fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16)); + fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32)); + fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32)); + fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32)); + fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32)); + fprintf(stderr, "%lu\n", rol(a, b, 64)); + fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8)); + fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8)); + fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8)); + fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8)); + fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16)); + fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16)); + fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16)); + fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16)); + fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32)); + fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32)); + fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32)); + fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32)); + fprintf(stderr, "%lu\n", ror(a, b, 64)); + fprintf(stderr, "%lu\n%lu\n", mod(a, 8), mod(a, 8)); + fprintf(stderr, "%lu\n%lu\n", mod(a, 16), mod(a, 16)); + fprintf(stderr, "%lu\n%lu\n", mod(a, 32), mod(a, 32)); + fprintf(stderr, "%lu\n", a); + } + + return 0; +} diff --git a/scripts/fuzz_prep.sh b/scripts/fuzz_prep.sh new file mode 100755 index 000000000000..0441f94e340c --- /dev/null +++ b/scripts/fuzz_prep.sh @@ -0,0 +1,81 @@ +#! /bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +# Just print the usage and exit with an error. +usage() { + printf 'usage: %s [-a] [afl_compiler]\n' "$0" 1>&2 + printf '\n' + printf ' If -a is given, then an ASan ready build is created.\n' + printf ' Otherwise, a normal fuzz build is created.\n' + printf ' The ASan-ready build is for running under\n' + printf ' `tests/afl.py --asan`, which checks that there were no\n' + printf ' memory errors in any path found by the fuzzer.\n' + printf ' It might also be useful to run scripts/randmath.py on an\n' + printf ' ASan-ready binary.\n' + exit 1 +} + +script="$0" +scriptdir=$(dirname "$script") + +asan=0 + +# Process command-line arguments. +while getopts "a" opt; do + + case "$opt" in + a) asan=1 ; shift ;; + ?) usage "Invalid option: $opt" ;; + esac + +done + +if [ $# -lt 1 ]; then + CC=afl-clang-lto +else + CC="$1" +fi + +# We want this for extra sensitive crashing +AFL_HARDEN=1 + +cd "$scriptdir/.." + +set -e + +if [ "$asan" -ne 0 ]; then + CFLAGS="-flto -fsanitize=address" +else + CFLAGS="-flto" +fi + +# We want a debug build because asserts are counted as crashes too. +CC="$CC" CFLAGS="$CFLAGS" ./configure.sh -gO3 -z + +make -j16 diff --git a/scripts/manpage.sh b/scripts/manpage.sh new file mode 100755 index 000000000000..c1429a6ed51f --- /dev/null +++ b/scripts/manpage.sh @@ -0,0 +1,175 @@ +#! /bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +# Print the usage and exit with an error. +usage() { + printf "usage: %s manpage\n" "$0" 1>&2 + exit 1 +} + +# Generate a manpage and print it to a file. +# @param md The markdown manual to generate a manpage for. +# @param out The file to print the manpage to. +gen_manpage() { + + _gen_manpage_md="$1" + shift + + _gen_manpage_out="$1" + shift + + cat "$manualsdir/header.txt" > "$_gen_manpage_out" + cat "$manualsdir/header_${manpage}.txt" >> "$_gen_manpage_out" + + pandoc -f commonmark_x -t man "$_gen_manpage_md" >> "$_gen_manpage_out" +} + +# Generate a manual from a template and print it to a file before generating +# its manpage. +# param args The type of markdown manual to generate. This is a string that +# corresponds to build type (see the Build Type section of the +# manuals/build.md manual). +gen_manual() { + + _gen_manual_args="$1" + shift + + # Set up some local variables. $manualsdir and $manpage from from the + # variables outside the function. + _gen_manual_status="$ALL" + _gen_manual_out="$manualsdir/$manpage/$_gen_manual_args.1" + _gen_manual_md="$manualsdir/$manpage/$_gen_manual_args.1.md" + _gen_manual_temp="$manualsdir/temp.1.md" + + # We need to set IFS, so we store it here for restoration later. + _gen_manual_ifs="$IFS" + + # Remove the files that will be generated. + rm -rf "$_gen_manual_out" "$_gen_manual_md" + + # Here is the magic. This loop reads the template line-by-line, and based on + # _gen_manual_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 line; do + + # If we have found an end, reset the status. + if [ "$line" = "{{ end }}" ]; then + + # Some error checking. This helps when editing the templates. + if [ "$_gen_manual_status" -eq "$ALL" ]; then + err_exit "{{ end }} tag without corresponding start tag" 2 + fi + + _gen_manual_status="$ALL" + + # We have found a tag that allows our build type to use it. + elif [ "${line#\{\{* $_gen_manual_args *\}\}}" != "$line" ]; then + + # More error checking. We don't want tags nested. + if [ "$_gen_manual_status" -ne "$ALL" ]; then + err_exit "start tag nested in start tag" 3 + fi + + _gen_manual_status="$NOSKIP" + + # We have found a tag that is *not* allowed for our build type. + elif [ "${line#\{\{*\}\}}" != "$line" ]; then + + if [ "$_gen_manual_status" -ne "$ALL" ]; then + err_exit "start tag nested in start tag" 3 + fi + + _gen_manual_status="$SKIP" + + # This is for normal lines. If we are not skipping, print. + else + if [ "$_gen_manual_status" -ne "$SKIP" ]; then + printf '%s\n' "$line" >> "$_gen_manual_temp" + fi + fi + + done < "$manualsdir/${manpage}.1.md.in" + + # Remove multiple blank lines. + uniq "$_gen_manual_temp" "$_gen_manual_md" + + # Remove the temp file. + rm -rf "$_gen_manual_temp" + + # Reset IFS. + IFS="$_gen_manual_ifs" + + # Generate the manpage. + gen_manpage "$_gen_manual_md" "$_gen_manual_out" +} + +set -e + +script="$0" +scriptdir=$(dirname "$script") +manualsdir="$scriptdir/../manuals" + +. "$scriptdir/functions.sh" + +# Constants for use later. If the set of build types is changed, $ARGS must be +# updated. +ARGS="A E H N EH EN HN EHN" +ALL=0 +NOSKIP=1 +SKIP=2 + +# Process command-line arguments. +test "$#" -eq 1 || usage + +manpage="$1" +shift + +if [ "$manpage" != "bcl" ]; then + + # Generate a manual and manpage for each build type. + for a in $ARGS; do + gen_manual "$a" + done + +else + # For bcl, just generate the manpage. + gen_manpage "$manualsdir/${manpage}.3.md" "$manualsdir/${manpage}.3" +fi diff --git a/scripts/ministat.c b/scripts/ministat.c new file mode 100644 index 000000000000..e5b7cd47b3e4 --- /dev/null +++ b/scripts/ministat.c @@ -0,0 +1,675 @@ +/*- + * SPDX-License-Identifier: Beerware + * + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + */ + +#ifdef __GNU_LIBRARY__ +#include <sys/cdefs.h> +#endif // __GNU_LIBRARY__ + +#include <sys/ioctl.h> + +#ifdef __GNU_LIBRARY__ +#include <sys/queue.h> +#endif // __GNU_LIBRARY__ + +#include <assert.h> +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define NSTUDENT 100 +#define NCONF 6 +static double const studentpct[] = { 80, 90, 95, 98, 99, 99.5 }; +static double const student[NSTUDENT + 1][NCONF] = { +/* inf */ { 1.282, 1.645, 1.960, 2.326, 2.576, 3.090 }, +/* 1. */ { 3.078, 6.314, 12.706, 31.821, 63.657, 318.313 }, +/* 2. */ { 1.886, 2.920, 4.303, 6.965, 9.925, 22.327 }, +/* 3. */ { 1.638, 2.353, 3.182, 4.541, 5.841, 10.215 }, +/* 4. */ { 1.533, 2.132, 2.776, 3.747, 4.604, 7.173 }, +/* 5. */ { 1.476, 2.015, 2.571, 3.365, 4.032, 5.893 }, +/* 6. */ { 1.440, 1.943, 2.447, 3.143, 3.707, 5.208 }, +/* 7. */ { 1.415, 1.895, 2.365, 2.998, 3.499, 4.782 }, +/* 8. */ { 1.397, 1.860, 2.306, 2.896, 3.355, 4.499 }, +/* 9. */ { 1.383, 1.833, 2.262, 2.821, 3.250, 4.296 }, +/* 10. */ { 1.372, 1.812, 2.228, 2.764, 3.169, 4.143 }, +/* 11. */ { 1.363, 1.796, 2.201, 2.718, 3.106, 4.024 }, +/* 12. */ { 1.356, 1.782, 2.179, 2.681, 3.055, 3.929 }, +/* 13. */ { 1.350, 1.771, 2.160, 2.650, 3.012, 3.852 }, +/* 14. */ { 1.345, 1.761, 2.145, 2.624, 2.977, 3.787 }, +/* 15. */ { 1.341, 1.753, 2.131, 2.602, 2.947, 3.733 }, +/* 16. */ { 1.337, 1.746, 2.120, 2.583, 2.921, 3.686 }, +/* 17. */ { 1.333, 1.740, 2.110, 2.567, 2.898, 3.646 }, +/* 18. */ { 1.330, 1.734, 2.101, 2.552, 2.878, 3.610 }, +/* 19. */ { 1.328, 1.729, 2.093, 2.539, 2.861, 3.579 }, +/* 20. */ { 1.325, 1.725, 2.086, 2.528, 2.845, 3.552 }, +/* 21. */ { 1.323, 1.721, 2.080, 2.518, 2.831, 3.527 }, +/* 22. */ { 1.321, 1.717, 2.074, 2.508, 2.819, 3.505 }, +/* 23. */ { 1.319, 1.714, 2.069, 2.500, 2.807, 3.485 }, +/* 24. */ { 1.318, 1.711, 2.064, 2.492, 2.797, 3.467 }, +/* 25. */ { 1.316, 1.708, 2.060, 2.485, 2.787, 3.450 }, +/* 26. */ { 1.315, 1.706, 2.056, 2.479, 2.779, 3.435 }, +/* 27. */ { 1.314, 1.703, 2.052, 2.473, 2.771, 3.421 }, +/* 28. */ { 1.313, 1.701, 2.048, 2.467, 2.763, 3.408 }, +/* 29. */ { 1.311, 1.699, 2.045, 2.462, 2.756, 3.396 }, +/* 30. */ { 1.310, 1.697, 2.042, 2.457, 2.750, 3.385 }, +/* 31. */ { 1.309, 1.696, 2.040, 2.453, 2.744, 3.375 }, +/* 32. */ { 1.309, 1.694, 2.037, 2.449, 2.738, 3.365 }, +/* 33. */ { 1.308, 1.692, 2.035, 2.445, 2.733, 3.356 }, +/* 34. */ { 1.307, 1.691, 2.032, 2.441, 2.728, 3.348 }, +/* 35. */ { 1.306, 1.690, 2.030, 2.438, 2.724, 3.340 }, +/* 36. */ { 1.306, 1.688, 2.028, 2.434, 2.719, 3.333 }, +/* 37. */ { 1.305, 1.687, 2.026, 2.431, 2.715, 3.326 }, +/* 38. */ { 1.304, 1.686, 2.024, 2.429, 2.712, 3.319 }, +/* 39. */ { 1.304, 1.685, 2.023, 2.426, 2.708, 3.313 }, +/* 40. */ { 1.303, 1.684, 2.021, 2.423, 2.704, 3.307 }, +/* 41. */ { 1.303, 1.683, 2.020, 2.421, 2.701, 3.301 }, +/* 42. */ { 1.302, 1.682, 2.018, 2.418, 2.698, 3.296 }, +/* 43. */ { 1.302, 1.681, 2.017, 2.416, 2.695, 3.291 }, +/* 44. */ { 1.301, 1.680, 2.015, 2.414, 2.692, 3.286 }, +/* 45. */ { 1.301, 1.679, 2.014, 2.412, 2.690, 3.281 }, +/* 46. */ { 1.300, 1.679, 2.013, 2.410, 2.687, 3.277 }, +/* 47. */ { 1.300, 1.678, 2.012, 2.408, 2.685, 3.273 }, +/* 48. */ { 1.299, 1.677, 2.011, 2.407, 2.682, 3.269 }, +/* 49. */ { 1.299, 1.677, 2.010, 2.405, 2.680, 3.265 }, +/* 50. */ { 1.299, 1.676, 2.009, 2.403, 2.678, 3.261 }, +/* 51. */ { 1.298, 1.675, 2.008, 2.402, 2.676, 3.258 }, +/* 52. */ { 1.298, 1.675, 2.007, 2.400, 2.674, 3.255 }, +/* 53. */ { 1.298, 1.674, 2.006, 2.399, 2.672, 3.251 }, +/* 54. */ { 1.297, 1.674, 2.005, 2.397, 2.670, 3.248 }, +/* 55. */ { 1.297, 1.673, 2.004, 2.396, 2.668, 3.245 }, +/* 56. */ { 1.297, 1.673, 2.003, 2.395, 2.667, 3.242 }, +/* 57. */ { 1.297, 1.672, 2.002, 2.394, 2.665, 3.239 }, +/* 58. */ { 1.296, 1.672, 2.002, 2.392, 2.663, 3.237 }, +/* 59. */ { 1.296, 1.671, 2.001, 2.391, 2.662, 3.234 }, +/* 60. */ { 1.296, 1.671, 2.000, 2.390, 2.660, 3.232 }, +/* 61. */ { 1.296, 1.670, 2.000, 2.389, 2.659, 3.229 }, +/* 62. */ { 1.295, 1.670, 1.999, 2.388, 2.657, 3.227 }, +/* 63. */ { 1.295, 1.669, 1.998, 2.387, 2.656, 3.225 }, +/* 64. */ { 1.295, 1.669, 1.998, 2.386, 2.655, 3.223 }, +/* 65. */ { 1.295, 1.669, 1.997, 2.385, 2.654, 3.220 }, +/* 66. */ { 1.295, 1.668, 1.997, 2.384, 2.652, 3.218 }, +/* 67. */ { 1.294, 1.668, 1.996, 2.383, 2.651, 3.216 }, +/* 68. */ { 1.294, 1.668, 1.995, 2.382, 2.650, 3.214 }, +/* 69. */ { 1.294, 1.667, 1.995, 2.382, 2.649, 3.213 }, +/* 70. */ { 1.294, 1.667, 1.994, 2.381, 2.648, 3.211 }, +/* 71. */ { 1.294, 1.667, 1.994, 2.380, 2.647, 3.209 }, +/* 72. */ { 1.293, 1.666, 1.993, 2.379, 2.646, 3.207 }, +/* 73. */ { 1.293, 1.666, 1.993, 2.379, 2.645, 3.206 }, +/* 74. */ { 1.293, 1.666, 1.993, 2.378, 2.644, 3.204 }, +/* 75. */ { 1.293, 1.665, 1.992, 2.377, 2.643, 3.202 }, +/* 76. */ { 1.293, 1.665, 1.992, 2.376, 2.642, 3.201 }, +/* 77. */ { 1.293, 1.665, 1.991, 2.376, 2.641, 3.199 }, +/* 78. */ { 1.292, 1.665, 1.991, 2.375, 2.640, 3.198 }, +/* 79. */ { 1.292, 1.664, 1.990, 2.374, 2.640, 3.197 }, +/* 80. */ { 1.292, 1.664, 1.990, 2.374, 2.639, 3.195 }, +/* 81. */ { 1.292, 1.664, 1.990, 2.373, 2.638, 3.194 }, +/* 82. */ { 1.292, 1.664, 1.989, 2.373, 2.637, 3.193 }, +/* 83. */ { 1.292, 1.663, 1.989, 2.372, 2.636, 3.191 }, +/* 84. */ { 1.292, 1.663, 1.989, 2.372, 2.636, 3.190 }, +/* 85. */ { 1.292, 1.663, 1.988, 2.371, 2.635, 3.189 }, +/* 86. */ { 1.291, 1.663, 1.988, 2.370, 2.634, 3.188 }, +/* 87. */ { 1.291, 1.663, 1.988, 2.370, 2.634, 3.187 }, +/* 88. */ { 1.291, 1.662, 1.987, 2.369, 2.633, 3.185 }, +/* 89. */ { 1.291, 1.662, 1.987, 2.369, 2.632, 3.184 }, +/* 90. */ { 1.291, 1.662, 1.987, 2.368, 2.632, 3.183 }, +/* 91. */ { 1.291, 1.662, 1.986, 2.368, 2.631, 3.182 }, +/* 92. */ { 1.291, 1.662, 1.986, 2.368, 2.630, 3.181 }, +/* 93. */ { 1.291, 1.661, 1.986, 2.367, 2.630, 3.180 }, +/* 94. */ { 1.291, 1.661, 1.986, 2.367, 2.629, 3.179 }, +/* 95. */ { 1.291, 1.661, 1.985, 2.366, 2.629, 3.178 }, +/* 96. */ { 1.290, 1.661, 1.985, 2.366, 2.628, 3.177 }, +/* 97. */ { 1.290, 1.661, 1.985, 2.365, 2.627, 3.176 }, +/* 98. */ { 1.290, 1.661, 1.984, 2.365, 2.627, 3.175 }, +/* 99. */ { 1.290, 1.660, 1.984, 2.365, 2.626, 3.175 }, +/* 100. */ { 1.290, 1.660, 1.984, 2.364, 2.626, 3.174 } +}; + +#define MAX_DS 8 +static char symbol[MAX_DS] = { ' ', 'x', '+', '*', '%', '#', '@', 'O' }; + +struct dataset { + char *name; + double *points; + size_t lpoints; + double sy, syy; + size_t n; +}; + +static struct dataset * +NewSet(void) +{ + struct dataset *ds; + + ds = calloc(1, sizeof *ds); + assert(ds != NULL); + ds->lpoints = 100000; + ds->points = calloc(sizeof *ds->points, ds->lpoints); + assert(ds->points != NULL); + ds->syy = NAN; + return(ds); +} + +static void +AddPoint(struct dataset *ds, double a) +{ + double *dp; + + if (ds->n >= ds->lpoints) { + dp = ds->points; + ds->lpoints *= 4; + ds->points = calloc(sizeof *ds->points, ds->lpoints); + assert(ds->points != NULL); + memcpy(ds->points, dp, sizeof *dp * ds->n); + free(dp); + } + ds->points[ds->n++] = a; + ds->sy += a; +} + +static double +Min(const struct dataset *ds) +{ + + return (ds->points[0]); +} + +static double +Max(const struct dataset *ds) +{ + + return (ds->points[ds->n -1]); +} + +static double +Avg(const struct dataset *ds) +{ + + return(ds->sy / ds->n); +} + +static double +Median(const struct dataset *ds) +{ + const size_t m = ds->n / 2; + + if ((ds->n % 2) == 0) + return ((ds->points[m] + (ds->points[m - 1])) / 2); + return (ds->points[m]); +} + +static double +Var(struct dataset *ds) +{ + size_t z; + const double a = Avg(ds); + + if (isnan(ds->syy)) { + ds->syy = 0.0; + for (z = 0; z < ds->n; z++) + ds->syy += (ds->points[z] - a) * (ds->points[z] - a); + } + + return (ds->syy / (ds->n - 1.0)); +} + +static double +Stddev(struct dataset *ds) +{ + + return sqrt(Var(ds)); +} + +static void +VitalsHead(void) +{ + + printf(" N Min Max Median Avg Stddev\n"); +} + +static void +Vitals(struct dataset *ds, int flag) +{ + + printf("%c %3zu %13.8g %13.8g %13.8g %13.8g %13.8g", symbol[flag], + ds->n, Min(ds), Max(ds), Median(ds), Avg(ds), Stddev(ds)); + printf("\n"); +} + +static void +Relative(struct dataset *ds, struct dataset *rs, int confidx) +{ + double spool, s, d, e, t; + double re; + size_t z; + + z = ds->n + rs->n - 2; + if (z > NSTUDENT) + t = student[0][confidx]; + else + t = student[z][confidx]; + spool = (ds->n - 1) * Var(ds) + (rs->n - 1) * Var(rs); + spool /= ds->n + rs->n - 2; + spool = sqrt(spool); + s = spool * sqrt(1.0 / ds->n + 1.0 / rs->n); + d = Avg(ds) - Avg(rs); + e = t * s; + + re = (ds->n - 1) * Var(ds) + (rs->n - 1) * Var(rs) * + (Avg(ds) * Avg(ds)) / (Avg(rs) * Avg(rs)); + re *= (ds->n + rs->n) / (ds->n * rs->n * (ds->n + rs->n - 2.0)); + re = t * sqrt(re); + + if (fabs(d) > e) { + printf("Difference at %.1f%% confidence\n", studentpct[confidx]); + printf(" %g +/- %g\n", d, e); + printf(" %g%% +/- %g%%\n", d * 100 / Avg(rs), re * 100 / Avg(rs)); + printf(" (Student's t, pooled s = %g)\n", spool); + } else { + printf("No difference proven at %.1f%% confidence\n", + studentpct[confidx]); + } +} + +struct plot { + double min; + double max; + double span; + int width; + + double x0, dx; + size_t height; + char *data; + char **bar; + int separate_bars; + int num_datasets; +}; + +static struct plot plot; + +static void +SetupPlot(int width, int separate, int num_datasets) +{ + struct plot *pl; + + pl = &plot; + pl->width = width; + pl->height = 0; + pl->data = NULL; + pl->bar = NULL; + pl->separate_bars = separate; + pl->num_datasets = num_datasets; + pl->min = 999e99; + pl->max = -999e99; +} + +static void +AdjPlot(double a) +{ + struct plot *pl; + + pl = &plot; + if (a < pl->min) + pl->min = a; + if (a > pl->max) + pl->max = a; + pl->span = pl->max - pl->min; + pl->dx = pl->span / (pl->width - 1.0); + pl->x0 = pl->min - .5 * pl->dx; +} + +static void +DimPlot(struct dataset *ds) +{ + AdjPlot(Min(ds)); + AdjPlot(Max(ds)); + AdjPlot(Avg(ds) - Stddev(ds)); + AdjPlot(Avg(ds) + Stddev(ds)); +} + +static void +PlotSet(struct dataset *ds, int val) +{ + struct plot *pl; + int i, x; + size_t m, j, z; + size_t n; + int bar; + double av, sd; + + pl = &plot; + if (pl->span == 0) + return; + + if (pl->separate_bars) + bar = val-1; + else + bar = 0; + + if (pl->bar == NULL) { + pl->bar = calloc(sizeof(char *), pl->num_datasets); + assert(pl->bar != NULL); + } + + if (pl->bar[bar] == NULL) { + pl->bar[bar] = malloc(pl->width); + assert(pl->bar[bar] != NULL); + memset(pl->bar[bar], 0, pl->width); + } + + m = 1; + i = -1; + j = 0; + /* Set m to max(j) + 1, to allocate required memory */ + for (n = 0; n < ds->n; n++) { + x = (ds->points[n] - pl->x0) / pl->dx; + if (x == i) { + j++; + if (j > m) + m = j; + } else { + j = 1; + i = x; + } + } + m += 1; + if (m > pl->height) { + pl->data = realloc(pl->data, pl->width * m); + assert(pl->data != NULL); + memset(pl->data + pl->height * pl->width, 0, + (m - pl->height) * pl->width); + } + pl->height = m; + i = -1; + for (n = 0; n < ds->n; n++) { + x = (ds->points[n] - pl->x0) / pl->dx; + if (x == i) { + j++; + } else { + j = 1; + i = x; + } + pl->data[j * pl->width + x] |= val; + } + av = Avg(ds); + sd = Stddev(ds); + if (!isnan(sd)) { + x = ((av - sd) - pl->x0) / pl->dx; + m = ((av + sd) - pl->x0) / pl->dx; + pl->bar[bar][m] = '|'; + pl->bar[bar][x] = '|'; + for (z = x + 1; z < m; z++) + if (pl->bar[bar][z] == 0) + pl->bar[bar][z] = '_'; + } + x = (Median(ds) - pl->x0) / pl->dx; + pl->bar[bar][x] = 'M'; + x = (av - pl->x0) / pl->dx; + pl->bar[bar][x] = 'A'; +} + +static void +DumpPlot(void) +{ + struct plot *pl; + int i, j, k; + size_t z; + + pl = &plot; + if (pl->span == 0) { + printf("[no plot, span is zero width]\n"); + return; + } + + putchar('+'); + for (i = 0; i < pl->width; i++) + putchar('-'); + putchar('+'); + putchar('\n'); + for (z = 1; z < pl->height; z++) { + putchar('|'); + for (j = 0; j < pl->width; j++) { + k = pl->data[(pl->height - z) * pl->width + j]; + if (k >= 0 && k < MAX_DS) + putchar(symbol[k]); + else + printf("[%02x]", k); + } + putchar('|'); + putchar('\n'); + } + for (i = 0; i < pl->num_datasets; i++) { + if (pl->bar[i] == NULL) + continue; + putchar('|'); + for (j = 0; j < pl->width; j++) { + k = pl->bar[i][j]; + if (k == 0) + k = ' '; + putchar(k); + } + putchar('|'); + putchar('\n'); + } + putchar('+'); + for (i = 0; i < pl->width; i++) + putchar('-'); + putchar('+'); + putchar('\n'); +} + +static int +dbl_cmp(const void *a, const void *b) +{ + const double *aa = a; + const double *bb = b; + + if (*aa < *bb) + return (-1); + else if (*aa > *bb) + return (1); + else + return (0); +} + +static struct dataset * +ReadSet(FILE *f, const char *n, int column, const char *delim) +{ + char buf[BUFSIZ], *p, *t; + struct dataset *s; + double d; + int line; + int i; + + s = NewSet(); + s->name = strdup(n); + assert(s->name != NULL); + line = 0; + while (fgets(buf, sizeof buf, f) != NULL) { + line++; + + i = strlen(buf); + while (i > 0 && isspace(buf[i - 1])) + buf[--i] = '\0'; + for (i = 1, t = strtok(buf, delim); + t != NULL && *t != '#'; + i++, t = strtok(NULL, delim)) { + if (i == column) + break; + } + if (t == NULL || *t == '#') + continue; + + d = strtod(t, &p); + if (p != NULL && *p != '\0') + errx(2, "Invalid data on line %d in %s", line, n); + if (*buf != '\0') + AddPoint(s, d); + } + if (s->n < 3) { + fprintf(stderr, + "Dataset %s must contain at least 3 data points\n", n); + exit (2); + } + qsort(s->points, s->n, sizeof *s->points, dbl_cmp); + return (s); +} + +static void +usage(char const *whine) +{ + int i; + + fprintf(stderr, "%s\n", whine); + fprintf(stderr, + "Usage: ministat [-C column] [-c confidence] [-d delimiter(s)] [-Ans] [-w width] [file [file ...]]\n"); + fprintf(stderr, "\tconfidence = {"); + for (i = 0; i < NCONF; i++) { + fprintf(stderr, "%s%g%%", + i ? ", " : "", + studentpct[i]); + } + fprintf(stderr, "}\n"); + fprintf(stderr, "\t-A : print statistics only. suppress the graph.\n"); + fprintf(stderr, "\t-C : column number to extract (starts and defaults to 1)\n"); + fprintf(stderr, "\t-d : delimiter(s) string, default to \" \\t\"\n"); + fprintf(stderr, "\t-n : print summary statistics only, no graph/test\n"); + fprintf(stderr, "\t-s : print avg/median/stddev bars on separate lines\n"); + fprintf(stderr, "\t-w : width of graph/test output (default 74 or terminal width)\n"); + exit (2); +} + +int +main(int argc, char **argv) +{ + const char *setfilenames[MAX_DS - 1]; + struct dataset *ds[MAX_DS - 1]; + FILE *setfiles[MAX_DS - 1]; + int nds; + double a; + const char *delim = " \t"; + char *p; + int c, i, ci; + int column = 1; + int flag_s = 0; + int flag_n = 0; + int termwidth = 74; + int suppress_plot = 0; + + if (isatty(STDOUT_FILENO)) { + struct winsize wsz; + + if ((p = getenv("COLUMNS")) != NULL && *p != '\0') + termwidth = atoi(p); + else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &wsz) != -1 && + wsz.ws_col > 0) + termwidth = wsz.ws_col - 2; + } + + ci = -1; + while ((c = getopt(argc, argv, "AC:c:d:snw:")) != -1) + switch (c) { + case 'A': + suppress_plot = 1; + break; + case 'C': + column = strtol(optarg, &p, 10); + if (p != NULL && *p != '\0') + usage("Invalid column number."); + if (column <= 0) + usage("Column number should be positive."); + break; + case 'c': + a = strtod(optarg, &p); + if (p != NULL && *p != '\0') + usage("Not a floating point number"); + for (i = 0; i < NCONF; i++) + if (a == studentpct[i]) + ci = i; + if (ci == -1) + usage("No support for confidence level"); + break; + case 'd': + if (*optarg == '\0') + usage("Can't use empty delimiter string"); + delim = optarg; + break; + case 'n': + flag_n = 1; + break; + case 's': + flag_s = 1; + break; + case 'w': + termwidth = strtol(optarg, &p, 10); + if (p != NULL && *p != '\0') + usage("Invalid width, not a number."); + if (termwidth < 0) + usage("Unable to move beyond left margin."); + break; + default: + usage("Unknown option"); + break; + } + if (ci == -1) + ci = 2; + argc -= optind; + argv += optind; + + if (argc == 0) { + setfilenames[0] = "<stdin>"; + setfiles[0] = stdin; + nds = 1; + } else { + if (argc > (MAX_DS - 1)) + usage("Too many datasets."); + nds = argc; + for (i = 0; i < nds; i++) { + setfilenames[i] = argv[i]; + if (!strcmp(argv[i], "-")) + setfiles[0] = stdin; + else + setfiles[i] = fopen(argv[i], "r"); + if (setfiles[i] == NULL) + err(2, "Cannot open %s", argv[i]); + } + } + + for (i = 0; i < nds; i++) { + ds[i] = ReadSet(setfiles[i], setfilenames[i], column, delim); + if (setfiles[i] != stdin) + fclose(setfiles[i]); + } + + for (i = 0; i < nds; i++) + printf("%c %s\n", symbol[i+1], ds[i]->name); + + if (!flag_n && !suppress_plot) { + SetupPlot(termwidth, flag_s, nds); + for (i = 0; i < nds; i++) + DimPlot(ds[i]); + for (i = 0; i < nds; i++) + PlotSet(ds[i], i + 1); + DumpPlot(); + } + VitalsHead(); + Vitals(ds[0], 1); + for (i = 1; i < nds; i++) { + Vitals(ds[i], i + 1); + if (!flag_n) + Relative(ds[i], ds[0], ci); + } + exit(0); +} diff --git a/scripts/package.sh b/scripts/package.sh new file mode 100755 index 000000000000..34692f7ab20a --- /dev/null +++ b/scripts/package.sh @@ -0,0 +1,248 @@ +#!/bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +# This script requires some non-POSIX utilities, but that's okay because it's +# really for maintainer use only. +# +# The non-POSIX utilities include: +# +# * git +# * stat +# * tar +# * xz +# * sha512sum +# * sha256sum +# * gpg +# * zip +# * unzip + +shasum() { + + f="$1" + shift + + # All this fancy stuff takes the sha512 and sha256 sums and signs it. The + # output after this point is what I usually copy into the release notes. + # (See manuals/release.md for more information.) + printf '$ sha512sum %s\n' "$f" + sha512sum "$f" + printf '\n' + printf '$ sha256sum %s\n' "$f" + sha256sum "$f" + printf '\n' + printf "$ stat -c '%%s %%n'\n" "$f" + stat -c '%s %n' "$f" + + if [ -f "$f.sig" ]; then + rm -f "$f.sig" + fi + + gpg --detach-sig -o "$f.sig" "$f" 2> /dev/null + + printf '\n' + printf '$ sha512sum %s.sig\n' "$f" + sha512sum "$f.sig" + printf '\n' + printf '$ sha256sum %s.sig\n' "$f" + sha256sum "$f.sig" + printf '\n' + printf "$ stat -c '%%s %%n'\n" "$f.sig" + stat -c '%s %n' "$f.sig" +} + +script="$0" +scriptdir=$(dirname "$script") + +repo="$scriptdir/.." +proj="bc" + +cd "$repo" + +if [ ! -f "../vs.zip" ]; then + printf 'Must have Windows builds!\n' + exit 1 +fi + +# We want the absolute path for later. +repo=$(pwd) + +# This convoluted mess does pull the version out. If you change the format of +# include/version.h, you may have to change this line. +version=$(cat include/version.h | grep "VERSION " - | awk '{ print $3 }' -) + +tag_msg="Version $version" +projver="${proj}-${version}" + +tempdir="/tmp/${projver}" +rm -rf $tempdir +mkdir -p $tempdir + +make clean_tests > /dev/null 2> /dev/null + +# Delete the tag and recreate it. This is the part of the script that makes it +# so you cannot run it twice on the same version, unless you know what you are +# doing. In fact, you cannot run it again if users have already started to use +# the old version of the tag. +if git rev-parse "$version" > /dev/null 2>&1; then + git push --delete origin "$version" > /dev/null 2> /dev/null + git tag --delete "$version" > /dev/null 2> /dev/null +fi + +git push > /dev/null 2> /dev/null +git tg "$version" -m "$tag_msg" > /dev/null 2> /dev/null +git push --tags > /dev/null 2> /dev/null + +# This line grabs the names of all of the files in .gitignore that still exist. +ignores=$(git check-ignore * **/*) + +cp -r ./* "$tempdir" + +cd $tempdir + +# Delete all the ignored files. +for i in $ignores; do + rm -rf "./$i" +done + +# This is a list of files that end users (including *software packagers* and +# *distro maintainers*!) do not care about. In particular, they *do* care about +# the testing infrastructure for the regular test suite because distro +# maintainers probably want to ensure the test suite runs. However, they +# probably don't care about fuzzing or other randomized testing. Also, I +# technically can't distribute tests/bc/scripts/timeconst.bc because it's from +# the Linux kernel, which is GPL. +extras=$(cat <<*EOF +.git/ +.gitignore +.gitattributes +benchmarks/ +manuals/bc.1.md.in +manuals/dc.1.md.in +manuals/benchmarks.md +manuals/development.md +manuals/header_bcl.txt +manuals/header_bc.txt +manuals/header_dc.txt +manuals/header.txt +manuals/release.md +scripts/afl.py +scripts/alloc.sh +scripts/benchmark.sh +scripts/bitfuncgen.c +scripts/fuzz_prep.sh +scripts/manpage.sh +scripts/ministat.c +scripts/package.sh +scripts/radamsa.sh +scripts/radamsa.txt +scripts/randmath.py +scripts/release_settings.txt +scripts/release.sh +scripts/test_settings.sh +scripts/test_settings.txt +tests/bc_outputs/ +tests/dc_outputs/ +tests/fuzzing/ +tests/bc/scripts/timeconst.bc +*EOF +) + +for i in $extras; do + rm -rf "./$i" +done + +cd .. + +parent="$repo/.." + +# Cleanup old stuff. +if [ -f "$projver.tar.xz" ]; then + rm -rf "$projver.tar.xz" +fi + +if [ -f "$projver.tar.xz.sig" ]; then + rm -rf "$projver.tar.xz.sig" +fi + +# Tar and compress and move into the parent directory of the repo. +tar cf "$projver.tar" "$projver/" +xz -z -v -9 -e "$projver.tar" > /dev/null 2> /dev/null +mv "$projver.tar.xz" "$parent" + +cd "$parent" + +# Clean up old Windows stuff. +if [ -d windows ]; then + rm -rf windows +fi + +if [ -f windows.zip ]; then + rm -rf $projver-windows.zip +fi + +# Prepare Windows stuff. +unzip vs.zip > /dev/null +mv vs windows + +# Remove unneeded Windows stuff. +rm -rf windows/*.vcxproj.user +rm -rf windows/src2 +rm -rf windows/tests +rm -rf windows/*.sln +rm -rf windows/*.vcxproj +rm -rf windows/*.vcxproj.filters + +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/*.obj +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/*.iobj +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.exe.recipe +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.ilk +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.log +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.tlog +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.pdb +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.ipdb +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/bc.vcxproj.FileListAbsolute.txt +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/strgen.exe +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/vc142.idb +rm -rf windows/bin/{Win32,x64}/{Debug,Release}/vc142.pdb + +rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/*.obj +rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.lib.recipe +rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.log +rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.tlog +rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.idb +rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.pdb +rm -rf windows/lib/{Win32,x64}/{Debug,ReleaseMD,ReleaseMT}/bcl.vcxproj.FileListAbsolute.txt + +# Zip the Windows stuff. +zip -r $projver-windows.zip windows > /dev/null + +printf '\n' +shasum "$projver.tar.xz" +printf '\n' +shasum "$projver-windows.zip" diff --git a/scripts/radamsa.sh b/scripts/radamsa.sh new file mode 100755 index 000000000000..c92923ddadc4 --- /dev/null +++ b/scripts/radamsa.sh @@ -0,0 +1,133 @@ +#! /bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +# This script uses some non-POSIX behavior, but since it's meant for bc +# maintainers only, I can accept that. + +# Get an entry from the file. If an argument exists, it is an index. Get that +# line. Otherwise, get a random line. +getentry() { + + # Figure out if we get a specific or random line. + if [ $# -gt 0 ]; then + entnum="$1" + else + entnum=0 + fi + + # Get data from stdin and figure out how many lines there are. + e=$(cat -) + num=$(printf '%s\n' "$e" | wc -l) + + # Figure out what line we are going to get. Uses bc's own PRNG. + if [ "$entnum" -eq 0 ]; then + rand=$(printf 'irand(%s) + 1\n' "$num" | "$bcdir/bc") + else + rand="$entnum" + fi + + # Get the line. + ent=$(printf '%s\n' "$e" | tail -n +$rand | head -n 1) + + printf '%s\n' "$ent" +} + +script="$0" +dir=$(dirname "$script") + +. "$dir/functions.sh" + +# Command-line processing. +if [ "$#" -lt 1 ]; then + printf 'usage: %s dir\n' "$0" + exit 1 +fi + +d="$1" +shift + +bcdir="$dir/../bin" + +# Figure out the correct input directory. +if [ "$d" = "bc" ]; then + inputs="$dir/../tests/fuzzing/bc_inputs1" + opts="-lq" +elif [ "$d" = "dc" ]; then + inputs="$dir/../test/fuzzing/dc_inputs" + opts="-x" +else + err_exit "wrong type of executable" 1 +fi + +export ASAN_OPTIONS="abort_on_error=1:allocator_may_return_null=1" + +entries=$(cat "$dir/radamsa.txt") + +IFS=$'\n' + +go=1 + +# Infinite loop. +while [ "$go" -ne 0 ]; do + + # If we are running bc, fuzz command-line arguments in BC_ENV_ARGS. + if [ "$d" = "bc" ]; then + + entry=$(cat -- "$dir/radamsa.txt" | getentry) + items=$(printf '%s\n' "$entry" | radamsa -n 10) + + printf '%s\n' "$items" + + for i in `seq 1 10`; do + + item=$(printf '%s\n' "$items" | getentry "$i") + + export BC_ENV_ARGS="$item" + echo 'halt' | "$bcdir/$d" + err=$? + + checkcrash "$d" "$err" "radamsa env args: \"$item\"" + done + + fi + + f=$(ls "$inputs" | getentry) + l=$(cat "$inputs/$f" | wc -l) + ll=$(printf '%s^2\n' "$l" | bc) + + # Fuzz on the AFL++ inputs. + for i in $(seq 1 2); do + data=$(cat "$inputs/$f" | radamsa -n 1) + printf '%s\n' "$data" > "$dir/../.log_${d}_test.txt" + printf '%s\n' "$data" | timeout -s SIGTERM 5 "$bcdir/$d" "$opts" > /dev/null + err=$? + checkcrash "$d" "$err" "radamsa stdin" + done + +done diff --git a/scripts/radamsa.txt b/scripts/radamsa.txt new file mode 100644 index 000000000000..4bf28907bead --- /dev/null +++ b/scripts/radamsa.txt @@ -0,0 +1,17 @@ +-lq '/home/gavin/.bcrc' +-lq "/home/gavin/.bcrc" +-lqg '/home/gavin/bc stuff.bc' +-lqg "/home/gavin/bc stuff.bc" +-lqg '/home/gavin/"bc" stuff.bc' +-lqg "/home/gavin/'bc' stuff.bc" +-lqg '/home/gavin/bc stuff.bc +-lqg "/home/gavin/bc stuff.bc +-lqg '/home/gavin/"bc" stuff.bc +-lqg "/home/gavin/'bc' stuff.bc +--mathlib --expand +--file="/home/gavin/.bcrc" +--file=/home/gavin/.bcrc +--file="/home/gavin/bc stuff.bc" +--file +--expression "4+4" +-e "irand(128)" -f /home/gavin/.bcrc diff --git a/scripts/randmath.py b/scripts/randmath.py new file mode 100755 index 000000000000..896f0e46c97f --- /dev/null +++ b/scripts/randmath.py @@ -0,0 +1,421 @@ +#! /usr/bin/python3 -B +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +import os, errno +import random +import sys +import subprocess + +# I want line length to *not* affect differences between the two, so I set it +# as high as possible. +env = { + "BC_LINE_LENGTH": "65535", + "DC_LINE_LENGTH": "65535" +} + + +# Generate a random integer between 0 and 2^limit. +# @param limit The power of two for the upper limit. +def gen(limit=4): + return random.randint(0, 2 ** (8 * limit)) + + +# Returns a random boolean for whether a number should be negative or not. +def negative(): + return random.randint(0, 1) == 1 + + +# Returns a random boolean for whether a number should be 0 or not. I decided to +# have it be 0 every 2^4 times since sometimes it is used to make a number less +# than 1. +def zero(): + return random.randint(0, 2 ** (4) - 1) == 0 + + +# Generate a real portion of a number. +def gen_real(): + + # Figure out if we should have a real portion. If so generate it. + if negative(): + n = str(gen(25)) + length = gen(7 / 8) + if len(n) < length: + n = ("0" * (length - len(n))) + n + else: + n = "0" + + return n + + +# Generates a number (as a string) based on the parameters. +# @param op The operation under test. +# @param neg Whether the number can be negative. +# @param real Whether the number can be a non-integer. +# @param z Whether the number can be zero. +# @param limit The power of 2 upper limit for the number. +def num(op, neg, real, z, limit=4): + + # Handle zero first. + if z: + z = zero() + else: + z = False + + if z: + # Generate a real portion maybe + if real: + n = gen_real() + if n != "0": + return "0." + n + return "0" + + # Figure out if we should be negative. + if neg: + neg = negative() + + # Generate the integer portion. + g = gen(limit) + + # Figure out if we should have a real number. negative() is used to give a + # 50/50 chance of getting a negative number. + if real: + n = gen_real() + else: + n = "0" + + # Generate the string. + g = str(g) + if n != "0": + g = g + "." + n + + # Make sure to use the right negative sign. + if neg and g != "0": + if op != modexp: + g = "-" + g + else: + g = "_" + g + + return g + + +# Add a failed test to the list. +# @param test The test that failed. +# @param op The operation for the test. +def add(test, op): + tests.append(test) + gen_ops.append(op) + + +# Compare the output between the two. +# @param exe The executable under test. +# @param options The command-line options. +# @param p The object returned from subprocess.run() for the calculator +# under test. +# @param test The test. +# @param halt The halt string for the calculator under test. +# @param expected The expected result. +# @param op The operation under test. +# @param do_add If true, add a failing test to the list, otherwise, don't. +def compare(exe, options, p, test, halt, expected, op, do_add=True): + + # Check for error from the calculator under test. + if p.returncode != 0: + + print(" {} returned an error ({})".format(exe, p.returncode)) + + if do_add: + print(" adding to checklist...") + add(test, op) + + return + + actual = p.stdout.decode() + + # Check for a difference in output. + if actual != expected: + + if op >= exponent: + + # This is here because GNU bc, like mine can be flaky on the + # functions in the math library. This is basically testing if adding + # 10 to the scale works to make them match. If so, the difference is + # only because of that. + indata = "scale += 10; {}; {}".format(test, halt) + args = [ exe, options ] + p2 = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) + expected = p2.stdout[:-10].decode() + + if actual == expected: + print(" failed because of bug in other {}".format(exe)) + print(" continuing...") + return + + # Do the correct output for the situation. + if do_add: + print(" failed; adding to checklist...") + add(test, op) + else: + print(" failed {}".format(test)) + print(" expected:") + print(" {}".format(expected)) + print(" actual:") + print(" {}".format(actual)) + + +# Generates a test for op. I made sure that there was no clashing between +# calculators. Each calculator is responsible for certain ops. +# @param op The operation to test. +def gen_test(op): + + # First, figure out how big the scale should be. + scale = num(op, False, False, True, 5 / 8) + + # Do the right thing for each op. Generate the test based on the format + # string and the constraints of each op. For example, some ops can't accept + # 0 in some arguments, and some must have integers in some arguments. + if op < div: + s = fmts[op].format(scale, num(op, True, True, True), num(op, True, True, True)) + elif op == div or op == mod: + s = fmts[op].format(scale, num(op, True, True, True), num(op, True, True, False)) + elif op == power: + s = fmts[op].format(scale, num(op, True, True, True, 7 / 8), num(op, True, False, True, 6 / 8)) + elif op == modexp: + s = fmts[op].format(scale, num(op, True, False, True), num(op, True, False, True), + num(op, True, False, False)) + elif op == sqrt: + s = "1" + while s == "1": + s = num(op, False, True, True, 1) + s = fmts[op].format(scale, s) + else: + + if op == exponent: + first = num(op, True, True, True, 6 / 8) + elif op == bessel: + first = num(op, False, True, True, 6 / 8) + else: + first = num(op, True, True, True) + + if op != bessel: + s = fmts[op].format(scale, first) + else: + s = fmts[op].format(scale, first, 6 / 8) + + return s + + +# Runs a test with number t. +# @param t The number of the test. +def run_test(t): + + # Randomly select the operation. + op = random.randrange(bessel + 1) + + # Select the right calculator. + if op != modexp: + exe = "bc" + halt = "halt" + options = "-lq" + else: + exe = "dc" + halt = "q" + options = "" + + # Generate the test. + test = gen_test(op) + + # These don't work very well for some reason. + if "c(0)" in test or "scale = 4; j(4" in test: + return + + # Make sure the calculator will halt. + bcexe = exedir + "/" + exe + indata = test + "\n" + halt + + print("Test {}: {}".format(t, test)) + + # Only bc has options. + if exe == "bc": + args = [ exe, options ] + else: + args = [ exe ] + + # Run the GNU bc. + p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) + + output1 = p.stdout.decode() + + # Error checking for GNU. + if p.returncode != 0 or output1 == "": + print(" other {} returned an error ({}); continuing...".format(exe, p.returncode)) + return + + if output1 == "\n": + print(" other {} has a bug; continuing...".format(exe)) + return + + # Don't know why GNU has this problem... + if output1 == "-0\n": + output1 = "0\n" + elif output1 == "-0": + output1 = "0" + + args = [ bcexe, options ] + + # Run this bc/dc and compare. + p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) + compare(exe, options, p, test, halt, output1, op) + + +# This script must be run by itself. +if __name__ != "__main__": + sys.exit(1) + +script = sys.argv[0] +testdir = os.path.dirname(script) + +exedir = testdir + "/../bin" + +# The following are tables used to generate numbers. + +# The operations to test. +ops = [ '+', '-', '*', '/', '%', '^', '|' ] + +# The functions that can be tested. +funcs = [ "sqrt", "e", "l", "a", "s", "c", "j" ] + +# The files (corresponding to the operations with the functions appended) to add +# tests to if they fail. +files = [ "add", "subtract", "multiply", "divide", "modulus", "power", "modexp", + "sqrt", "exponent", "log", "arctangent", "sine", "cosine", "bessel" ] + +# The format strings corresponding to each operation and then each function. +fmts = [ "scale = {}; {} + {}", "scale = {}; {} - {}", "scale = {}; {} * {}", + "scale = {}; {} / {}", "scale = {}; {} % {}", "scale = {}; {} ^ {}", + "{}k {} {} {}|pR", "scale = {}; sqrt({})", "scale = {}; e({})", + "scale = {}; l({})", "scale = {}; a({})", "scale = {}; s({})", + "scale = {}; c({})", "scale = {}; j({}, {})" ] + +# Constants to make some code easier later. +div = 3 +mod = 4 +power = 5 +modexp = 6 +sqrt = 7 +exponent = 8 +bessel = 13 + +gen_ops = [] +tests = [] + +# Infinite loop until the user sends SIGINT. +try: + i = 0 + while True: + run_test(i) + i = i + 1 +except KeyboardInterrupt: + pass + +# This is where we start processing the checklist of possible failures. Why only +# possible failures? Because some operations, specifically the functions in the +# math library, are not guaranteed to be exactly correct. Because of that, we +# need to present every failed test to the user for a final check before we +# add them as test cases. + +# No items, just exit. +if len(tests) == 0: + print("\nNo items in checklist.") + print("Exiting") + sys.exit(0) + +print("\nGoing through the checklist...\n") + +# Just do some error checking. If this fails here, it's a bug in this script. +if len(tests) != len(gen_ops): + print("Corrupted checklist!") + print("Exiting...") + sys.exit(1) + +# Go through each item in the checklist. +for i in range(0, len(tests)): + + # Yes, there's some code duplication. Sue me. + + print("\n{}".format(tests[i])) + + op = int(gen_ops[i]) + + if op != modexp: + exe = "bc" + halt = "halt" + options = "-lq" + else: + exe = "dc" + halt = "q" + options = "" + + # We want to run the test again to show the user the difference. + indata = tests[i] + "\n" + halt + + args = [ exe, options ] + + p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) + + expected = p.stdout.decode() + + bcexe = exedir + "/" + exe + args = [ bcexe, options ] + + p = subprocess.run(args, input=indata.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) + + compare(exe, options, p, tests[i], halt, expected, op, False) + + # Ask the user to make a decision on the failed test. + answer = input("\nAdd test ({}/{}) to test suite? [y/N]: ".format(i + 1, len(tests))) + + # Quick and dirty answer parsing. + if 'Y' in answer or 'y' in answer: + + print("Yes") + + name = testdir + "/" + exe + "/" + files[op] + + # Write the test to the test file and the expected result to the + # results file. + with open(name + ".txt", "a") as f: + f.write(tests[i] + "\n") + + with open(name + "_results.txt", "a") as f: + f.write(expected) + + else: + print("No") + +print("Done!") diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 000000000000..12097b1cc8b9 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,810 @@ +#! /bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +# For OpenBSD, run using the following: +# +# scripts/release.sh 1 0 1 0 0 0 0 1 0 0 0 0 0 0 +# +# For FreeBSD, run using the following: +# +# scripts/release.sh 1 0 1 0 0 0 0 1 0 1 0 0 0 0 +# +# There is one problem with running this script on FreeBSD: it takes overcommit +# to the extreme. This means that some tests that try to create allocation +# failures instead make bc and dc crash. So running this script on FreeBSD does +# not work right now. +# +# For Linux, run two separate ones (in different checkouts), like so: +# +# scripts/release.sh 1 1 1 0 1 0 0 1 0 1 0 1 0 0 +# cd build; ../scripts/release.sh 1 1 0 1 0 1 0 1 0 1 0 0 1 1 +# +# Yes, I usually do sanitizers with Clang and Valgrind with GCC, and I also do +# out-of-source builds with GCC. +# +# To run sanitizers or Valgrind with generated tests, use the following: +# +# scripts/release.sh 1 1 1 0 1 0 0 1 0 1 0 1 0 0 +# cd build; ../scripts/release.sh 1 1 0 1 0 1 0 1 0 1 0 0 1 1 +# +# The reason I run history tests with GCC and not with Clang is because Clang +# already runs slower as a result of running with sanitizers, and the history +# tests are a little sensitive to load on a system. +# +# If this script fails on any platform when starting the Karatsuba test, check +# that Python is installed, especially if the error says something like: +# "karatsuba.py: not found". + +# Print the usage and exit with an error. Each parameter should be an integer. +# Non-zero activates, and zero deactivates. +usage() { + printf 'usage: %s [run_tests] [generate_tests] [test_with_clang] [test_with_gcc] \n' "$script" + printf ' [run_sanitizers] [run_valgrind] [test_settings] [run_64_bit] \n' + printf ' [run_gen_script] [test_c11] [test_128_bit] [test_computed_goto]\n' + printf ' [test_karatsuba] [test_history]\n' + exit 1 +} + +# Print a header with a message. This is just to make it easy to track progress. +# @param msg The message to print in the header. +header() { + + _header_msg="$1" + shift + + printf '\n' + printf '*******************\n' + printf "$_header_msg" + printf '\n' + printf '*******************\n' + printf '\n' +} + +# Easy way to call make. +do_make() { + # No reason to do 64 except to see if I actually can overload my system. :) + # Well, also that it might actually improve throughput as other jobs can run + # while some are waiting. + make -j64 "$@" +} + +# Run configure.sh. +# @param CFLAGS The CFLAGS. +# @param CC The C compiler. +# @param configure_flags The flags for configure.sh itself. +# @param GEN_HOST The setting for GEN_HOST. +# @param LONG_BIT The setting for LONG_BIT. +configure() { + + _configure_CFLAGS="$1" + shift + + _configure_CC="$1" + shift + + _configure_configure_flags="$1" + shift + + _configure_GEN_HOST="$1" + shift + + _configure_LONG_BIT="$1" + shift + + # Make sure to not generate tests if necessary. + if [ "$gen_tests" -eq 0 ]; then + _configure_configure_flags="-G $_configure_configure_flags" + fi + + # Choose the right extra flags. + if [ "$_configure_CC" = "clang" ]; then + _configure_CFLAGS="$clang_flags $_configure_CFLAGS" + elif [ "$_configure_CC" = "gcc" ]; then + _configure_CFLAGS="$gcc_flags $_configure_CFLAGS" + fi + + # Print the header and do the job. + _configure_header=$(printf 'Running configure.sh %s ...' "$_configure_configure_flags") + _configure_header=$(printf "$_configure_header\n CC=\"%s\"\n" "$_configure_CC") + _configure_header=$(printf "$_configure_header\n CFLAGS=\"%s\"\n" "$_configure_CFLAGS") + _configure_header=$(printf "$_configure_header\n LONG_BIT=%s" "$_configure_LONG_BIT") + _configure_header=$(printf "$_configure_header\n GEN_HOST=%s" "$_configure_GEN_HOST") + + header "$_configure_header" + CFLAGS="$_configure_CFLAGS" CC="$_configure_CC" GEN_HOST="$_configure_GEN_HOST" \ + LONG_BIT="$_configure_LONG_BIT" "$real/configure.sh" $_configure_configure_flags > /dev/null +} + +# Build with make. This function also captures and outputs any warnings if they +# exists because as far as I am concerned, warnings are not acceptable for +# release. +# @param CFLAGS The CFLAGS. +# @param CC The C compiler. +# @param configure_flags The flags for configure.sh itself. +# @param GEN_HOST The setting for GEN_HOST. +# @param LONG_BIT The setting for LONG_BIT. +build() { + + _build_CFLAGS="$1" + shift + + _build_CC="$1" + shift + + _build_configure_flags="$1" + shift + + _build_GEN_HOST="$1" + shift + + _build_LONG_BIT="$1" + shift + + configure "$_build_CFLAGS" "$_build_CC" "$_build_configure_flags" "$_build_GEN_HOST" "$_build_LONG_BIT" + + _build_header=$(printf 'Building...\n CC=%s' "$_build_CC") + _build_header=$(printf "$_build_header\n CFLAGS=\"%s\"" "$_build_CFLAGS") + _build_header=$(printf "$_build_header\n LONG_BIT=%s" "$_build_LONG_BIT") + _build_header=$(printf "$_build_header\n GEN_HOST=%s" "$_build_GEN_HOST") + + header "$_build_header" + + # Capture and print warnings. + do_make > /dev/null 2> "./.test.txt" + + if [ -s "./.test.txt" ]; then + printf '%s generated warning(s):\n' "$_build_CC" + printf '\n' + cat "./.test.txt" + exit 1 + fi +} + +# Run tests with make. +runtest() { + + header "Running tests" + + if [ "$#" -gt 0 ]; then + do_make "$@" + else + + do_make test + + if [ "$test_history" -ne 0 ]; then + do_make test_history + fi + fi +} + +# Builds and runs tests with both calculators, then bc only, then dc only. If +# run_tests is false, then it just does the builds. +# @param CFLAGS The CFLAGS. +# @param CC The C compiler. +# @param configure_flags The flags for configure.sh itself. +# @param GEN_HOST The setting for GEN_HOST. +# @param LONG_BIT The setting for LONG_BIT. +# @param run_tests Whether to run tests or not. +runconfigtests() { + + _runconfigtests_CFLAGS="$1" + shift + + _runconfigtests_CC="$1" + shift + + _runconfigtests_configure_flags="$1" + shift + + _runconfigtests_GEN_HOST="$1" + shift + + _runconfigtests_LONG_BIT="$1" + shift + + _runconfigtests_run_tests="$1" + shift + + if [ "$_runconfigtests_run_tests" -ne 0 ]; then + _runconfigtests_header=$(printf 'Running tests with configure flags') + else + _runconfigtests_header=$(printf 'Building with configure flags') + fi + + _runconfigtests_header=$(printf "$_runconfigtests_header \"%s\" ...\n" "$_runconfigtests_configure_flags") + _runconfigtests_header=$(printf "$_runconfigtests_header\n CC=%s\n" "$_runconfigseries_CC") + _runconfigtests_header=$(printf "$_runconfigtests_header\n CFLAGS=\"%s\"" "$_runconfigseries_CFLAGS") + _runconfigtests_header=$(printf "$_runconfigtests_header\n LONG_BIT=%s" "$_runconfigtests_LONG_BIT") + _runconfigtests_header=$(printf "$_runconfigtests_header\n GEN_HOST=%s" "$_runconfigtests_GEN_HOST") + + header "$_runconfigtests_header" + + build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ + "$_runconfigtests_configure_flags" "$_runconfigtests_GEN_HOST" \ + "$_runconfigtests_LONG_BIT" + + if [ "$_runconfigtests_run_tests" -ne 0 ]; then + runtest + fi + + do_make clean + + build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ + "$_runconfigtests_configure_flags -b" "$_runconfigtests_GEN_HOST" \ + "$_runconfigtests_LONG_BIT" + + if [ "$_runconfigtests_run_tests" -ne 0 ]; then + runtest + fi + + do_make clean + + build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ + "$_runconfigtests_configure_flags -d" "$_runconfigtests_GEN_HOST" \ + "$_runconfigtests_LONG_BIT" + + if [ "$_runconfigtests_run_tests" -ne 0 ]; then + runtest + fi + + do_make clean +} + +# Builds and runs tests with runconfigtests(), but also does 64-bit, 32-bit, and +# 128-bit rand, if requested. It also does it with the gen script (strgen.sh) if +# requested. If run_tests is false, it just does the builds. +# @param CFLAGS The CFLAGS. +# @param CC The C compiler. +# @param configure_flags The flags for configure.sh itself. +# @param run_tests Whether to run tests or not. +runconfigseries() { + + _runconfigseries_CFLAGS="$1" + shift + + _runconfigseries_CC="$1" + shift + + _runconfigseries_configure_flags="$1" + shift + + _runconfigseries_run_tests="$1" + shift + + if [ "$run_64_bit" -ne 0 ]; then + + if [ "$test_128_bit" -ne 0 ]; then + runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ + "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" + fi + + if [ "$run_gen_script" -ne 0 ]; then + runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ + "$_runconfigseries_configure_flags" 0 64 "$_runconfigseries_run_tests" + fi + + runconfigtests "$_runconfigseries_CFLAGS -DBC_RAND_BUILTIN=0" "$_runconfigseries_CC" \ + "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" + + fi + + runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ + "$_runconfigseries_configure_flags" 1 32 "$_runconfigseries_run_tests" + + if [ "$run_gen_script" -ne 0 ]; then + runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ + "$_runconfigseries_configure_flags" 0 32 "$_runconfigseries_run_tests" + fi +} + +# Builds and runs tests with each setting combo running runconfigseries(). If +# run_tests is false, it just does the builds. +# @param CFLAGS The CFLAGS. +# @param CC The C compiler. +# @param configure_flags The flags for configure.sh itself. +# @param run_tests Whether to run tests or not. +runsettingsseries() { + + _runsettingsseries_CFLAGS="$1" + shift + + _runsettingsseries_CC="$1" + shift + + _runsettingsseries_configure_flags="$1" + shift + + _runsettingsseries_run_tests="$1" + shift + + if [ "$test_settings" -ne 0 ]; then + + while read _runsettingsseries_s; do + runconfigseries "$_runsettingsseries_CFLAGS" "$_runsettingsseries_CC" \ + "$_runsettingsseries_configure_flags $_runsettingsseries_s" \ + "$_runsettingsseries_run_tests" + done < "$scriptdir/release_settings.txt" + + else + runconfigseries "$_runsettingsseries_CFLAGS" "$_runsettingsseries_CC" \ + "$_runsettingsseries_configure_flags" "$_runsettingsseries_run_tests" + fi +} + +# Builds and runs tests with each build type running runsettingsseries(). If +# run_tests is false, it just does the builds. +# @param CFLAGS The CFLAGS. +# @param CC The C compiler. +# @param configure_flags The flags for configure.sh itself. +# @param run_tests Whether to run tests or not. +runtestseries() { + + _runtestseries_CFLAGS="$1" + shift + + _runtestseries_CC="$1" + shift + + _runtestseries_configure_flags="$1" + shift + + _runtestseries_run_tests="$1" + shift + + _runtestseries_flags="E H N EH EN HN EHN" + + runsettingsseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ + "$_runtestseries_configure_flags" "$_runtestseries_run_tests" + + for _runtestseries_f in $_runtestseries_flags; do + runsettingsseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ + "$_runtestseries_configure_flags -$_runtestseries_f" "$_runtestseries_run_tests" + done +} + +# Builds and runs the tests for bcl. If run_tests is false, it just does the +# builds. +# @param CFLAGS The CFLAGS. +# @param CC The C compiler. +# @param configure_flags The flags for configure.sh itself. +# @param run_tests Whether to run tests or not. +runlibtests() { + + _runlibtests_CFLAGS="$1" + shift + + _runlibtests_CC="$1" + shift + + _runlibtests_configure_flags="$1" + shift + + _runlibtests_run_tests="$1" + shift + + _runlibtests_configure_flags="$_runlibtests_configure_flags -a" + + build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 64 + + if [ "$_runlibtests_run_tests" -ne 0 ]; then + runtest test + fi + + build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 32 + + if [ "$_runlibtests_run_tests" -ne 0 ]; then + runtest test + fi +} + +# Builds and runs tests under C99, then C11, if requested, using +# runtestseries(). If run_tests is false, it just does the builds. +# @param CFLAGS The CFLAGS. +# @param CC The C compiler. +# @param configure_flags The flags for configure.sh itself. +# @param run_tests Whether to run tests or not. +runtests() { + + _runtests_CFLAGS="$1" + shift + + _runtests_CC="$1" + shift + + _runtests_configure_flags="$1" + shift + + _runtests_run_tests="$1" + shift + + runtestseries "-std=c99 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" + + if [ "$test_c11" -ne 0 ]; then + runtestseries "-std=c11 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" + fi +} + +# Runs the karatsuba tests. +karatsuba() { + + header "Running Karatsuba tests" + do_make karatsuba_test +} + +# Builds and runs under valgrind. It runs both, bc only, then dc only. +vg() { + + header "Running valgrind" + + if [ "$run_64_bit" -ne 0 ]; then + _vg_bits=64 + else + _vg_bits=32 + fi + + build "$debug -std=c99" "gcc" "-O3 -gv" "1" "$_vg_bits" + runtest test + + do_make clean_config + + build "$debug -std=c99" "gcc" "-O3 -gvb" "1" "$_vg_bits" + runtest test + + do_make clean_config + + build "$debug -std=c99" "gcc" "-O3 -gvd" "1" "$_vg_bits" + runtest test + + do_make clean_config + + build "$debug -std=c99" "gcc" "-O3 -gva" "1" "$_vg_bits" + runtest test + + do_make clean_config +} + +# Builds the debug series and runs the tests if run_tests allows. If sanitizers +# are enabled, it also does UBSan. +# @param CC The C compiler. +# @param run_tests Whether to run tests or not. +debug() { + + _debug_CC="$1" + shift + + _debug_run_tests="$1" + shift + + + if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then + runtests "$debug -fsanitize=undefined" "$_debug_CC" "-gm" "$_debug_run_tests" + else + runtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests" + fi + + + if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then + runlibtests "$debug -fsanitize=undefined" "$_debug_CC" "-gm" "$_debug_run_tests" + else + runlibtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests" + fi +} + +# Builds the release series and runs the test if run_tests allows. +# @param CC The C compiler. +# @param run_tests Whether to run tests or not. +release() { + + _release_CC="$1" + shift + + _release_run_tests="$1" + shift + + runtests "$release" "$_release_CC" "-O3" "$_release_run_tests" + + runlibtests "$release" "$_release_CC" "-O3" "$_release_run_tests" +} + +# Builds the release debug series and runs the test if run_tests allows. If +# sanitizers are enabled, it also does ASan and MSan. +# @param CC The C compiler. +# @param run_tests Whether to run tests or not. +reldebug() { + + _reldebug_CC="$1" + shift + + _reldebug_run_tests="$1" + shift + + + if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then + runtests "$debug -fsanitize=address" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" + runtests "$debug -fsanitize=memory" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" + else + runtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" + fi + + + if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then + runlibtests "$debug -fsanitize=address" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" + runlibtests "$debug -fsanitize=memory" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" + else + runlibtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" + fi +} + +# Builds the min size release series and runs the test if run_tests allows. +# @param CC The C compiler. +# @param run_tests Whether to run tests or not. +minsize() { + + _minsize_CC="$1" + shift + + _minsize_run_tests="$1" + shift + + runtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests" + + runlibtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests" +} + +# Builds all sets: debug, release, release debug, and min size, and runs the +# tests if run_tests allows. +# @param CC The C compiler. +# @param run_tests Whether to run tests or not. +build_set() { + + _build_set_CC="$1" + shift + + _build_set_run_tests="$1" + shift + + debug "$_build_set_CC" "$_build_set_run_tests" + release "$_build_set_CC" "$_build_set_run_tests" + reldebug "$_build_set_CC" "$_build_set_run_tests" + minsize "$_build_set_CC" "$_build_set_run_tests" +} + +# Set some strict warning flags. Clang's -Weverything can be way too strict, so +# we actually have to turn off some things. +clang_flags="-Weverything -Wno-padded -Wno-switch-enum -Wno-format-nonliteral" +clang_flags="$clang_flags -Wno-cast-align -Wno-missing-noreturn -Wno-disabled-macro-expansion" +clang_flags="$clang_flags -Wno-unreachable-code -Wno-unreachable-code-return" +clang_flags="$clang_flags -Wno-implicit-fallthrough -Wno-unused-macros -Wno-gnu-label-as-value" +# -Wno-undef is here because Clang seems to think BC_C11 is undefined, when it's defined. +clang_flags="$clang_flags -Wno-undef" +gcc_flags="-Wno-maybe-uninitialized -Wno-clobbered" + +# Common CFLAGS. +cflags="-Wall -Wextra -Werror -pedantic -Wno-conditional-uninitialized" + +# Common debug and release flags. +debug="$cflags -fno-omit-frame-pointer" +release="$cflags -DNDEBUG" + +set -e + +script="$0" +scriptdir=$(dirname "$script") + +real=$(realpath "$scriptdir/../") + +# Whether to run tests. +if [ "$#" -gt 0 ]; then + run_tests="$1" + shift +else + run_tests=1 +fi + +# Whether to generate tests. On platforms like OpenBSD, there is no GNU bc to +# generate tests, so this must be off. +if [ "$#" -gt 0 ]; then + gen_tests="$1" + shift +else + gen_tests=1 +fi + +# Whether to test with clang. +if [ "$#" -gt 0 ]; then + test_with_clang="$1" + shift +else + test_with_clang=1 +fi + +# Whether to test with gcc. +if [ "$#" -gt 0 ]; then + test_with_gcc="$1" + shift +else + test_with_gcc=1 +fi + +# Whether to test with sanitizers. +if [ "$#" -gt 0 ]; then + run_sanitizers="$1" + shift +else + run_sanitizers=1 +fi + +# Whether to test with valgrind. +if [ "$#" -gt 0 ]; then + run_valgrind="$1" + shift +else + run_valgrind=1 +fi + +# Whether to test all settings combos. +if [ "$#" -gt 0 ]; then + test_settings="$1" + shift +else + test_settings=1 +fi + +# Whether to test 64-bit in addition to 32-bit. +if [ "$#" -gt 0 ]; then + run_64_bit="$1" + shift +else + run_64_bit=1 +fi + +# Whether to test with strgen.sh in addition to strgen.c. +if [ "$#" -gt 0 ]; then + run_gen_script="$1" + shift +else + run_gen_script=0 +fi + +# Whether to test on C11 in addition to C99. +if [ "$#" -gt 0 ]; then + test_c11="$1" + shift +else + test_c11=0 +fi + +# Whether to test 128-bit integers in addition to no 128-bit integers. +if [ "$#" -gt 0 ]; then + test_128_bit="$1" + shift +else + test_128_bit=0 +fi + +# Whether to test with computed goto or not. +if [ "$#" -gt 0 ]; then + test_computed_goto="$1" + shift +else + test_computed_goto=0 +fi + +# Whether to test history or not. +if [ "$#" -gt 0 ]; then + test_karatsuba="$1" + shift +else + test_karatsuba=1 +fi + +# Whether to test history or not. +if [ "$#" -gt 0 ]; then + test_history="$1" + shift +else + test_history=0 +fi + +if [ "$run_64_bit" -ne 0 ]; then + bits=64 +else + bits=32 +fi + +if [ "$test_computed_goto" -eq 0 ]; then + clang_flags="-DBC_NO_COMPUTED_GOTO $clang_flags" + gcc_flags="-DBC_NO_COMPUTED_GOTO $gcc_flags" +fi + +# Setup a default compiler. +if [ "$test_with_clang" -ne 0 ]; then + defcc="clang" +elif [ "$test_with_gcc" -ne 0 ]; then + defcc="gcc" +else + defcc="c99" +fi + +export ASAN_OPTIONS="abort_on_error=1,allocator_may_return_null=1:strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:detect_invalid_pointer_pairs=2" +export UBSAN_OPTIONS="print_stack_trace=1,silence_unsigned_overflow=1" + +build "$debug -std=c99" "$defcc" "-g" "1" "$bits" + +header "Running math library under --standard" + +# Make sure the math library is POSIX compliant. +printf 'quit\n' | bin/bc -ls + +do_make clean_tests + +# Run the clang build sets. +if [ "$test_with_clang" -ne 0 ]; then + build_set "clang" "$run_tests" +fi + +# Run the gcc build sets. +if [ "$test_with_gcc" -ne 0 ]; then + build_set "gcc" "$run_tests" +fi + +if [ "$run_tests" -ne 0 ]; then + + build "$release" "$defcc" "-O3" "1" "$bits" + + # Run karatsuba. + if [ "$test_karatsuba" -ne 0 ]; then + karatsuba + fi + + # Valgrind. + if [ "$run_valgrind" -ne 0 -a "$test_with_gcc" -ne 0 ]; then + vg + fi + + printf '\n' + printf 'Tests successful.\n' + + # I just assume that I am going to be fuzzing when I am done. + header "Building for AFL++..." + + "$scriptdir/fuzz_prep.sh" + + printf '\n' + printf 'Ready for scripts/randmath.py and for fuzzing.\n' + printf '\n' + printf 'Run scripts/randmath.py if you changed any math code.\n' + printf '\n' + printf 'Then if there are no problems, run the fuzzer.\n' + printf '\n' + printf 'Then run `scripts/fuzz_prep.sh -a`.\n' + printf '\n' + printf 'Then run `scripts/afl.py --asan`.\n' + +fi diff --git a/scripts/release_settings.txt b/scripts/release_settings.txt new file mode 100644 index 000000000000..1cf572347241 --- /dev/null +++ b/scripts/release_settings.txt @@ -0,0 +1,16 @@ +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt diff --git a/scripts/test_settings.sh b/scripts/test_settings.sh new file mode 100755 index 000000000000..563dbf0e58f3 --- /dev/null +++ b/scripts/test_settings.sh @@ -0,0 +1,77 @@ +#! /bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 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. +# + +# This script's argument is a number, which is the index of the setting set +# that is under test. This script is for maintainers only. +# +# The procedure is this: run the script with: +# +# ./scripts/test_settings.sh 1 +# +# Then run bc and dc to ensure their stuff is correct. Then run this script +# again with: +# +# ./scripts/test_settings.sh 2 +# +# And repeat. You can also test various environment variable sets with them. + +# Print the usage and exit with an error. +usage() { + printf 'usage: %s index\n' "$0" 1>&2 + exit 1 +} + +script="$0" +scriptdir=$(dirname "$script") + +cd "$scriptdir/.." + +test "$#" -eq 1 || usage + +target="$1" +shift + +line=0 + +# This loop just loops until it gets to the right line. Quick and dirty. +while read s; do + + line=$(printf '%s + 1\n' "$line" | bc) + + if [ "$line" -eq "$target" ]; then + + # Configure, build, and exit. + ./configure.sh -O3 $s + + make -j16 > /dev/null + + exit + fi + +done < "$scriptdir/test_settings.txt" diff --git a/scripts/test_settings.txt b/scripts/test_settings.txt new file mode 100644 index 000000000000..e6dd8ac92929 --- /dev/null +++ b/scripts/test_settings.txt @@ -0,0 +1,93 @@ +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-Sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -Sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -sbc.prompt -Sdc.prompt +-sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt +-Sbc.sigint_reset -Sdc.sigint_reset -Sbc.tty_mode -Sdc.tty_mode -Sbc.history -Sdc.history -Sbc.prompt -Sdc.prompt |
