1#! /bin/sh 2# 3# SPDX-License-Identifier: BSD-2-Clause 4# 5# Copyright (c) 2018-2024 Gavin D. Howard and contributors. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions are met: 9# 10# * Redistributions of source code must retain the above copyright notice, this 11# list of conditions and the following disclaimer. 12# 13# * Redistributions in binary form must reproduce the above copyright notice, 14# this list of conditions and the following disclaimer in the documentation 15# and/or other materials provided with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30# For macOS from Ventura on, run using the following: 31# 32# scripts/release.sh 1 1 0 1 0 0 0 0 1 0 1 1 1 0 0 0 0 33# 34# For OpenBSD, run using the following: 35# 36# scripts/release.sh 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 37# 38# For FreeBSD, run using the following: 39# 40# scripts/release.sh 1 1 0 1 1 0 0 0 1 0 1 0 1 0 0 1 1 41# 42# For Linux, run two separate ones (in different checkouts), like so: 43# 44# scripts/release.sh 1 1 1 1 0 1 0 0 1 0 1 0 1 0 0 1 1 45# cd build; ../scripts/release.sh 1 1 1 0 1 0 1 0 1 0 1 0 0 1 1 1 1 46# 47# Yes, I usually do sanitizers with Clang and Valgrind with GCC, and I also do 48# out-of-source builds with GCC. 49# 50# The reason I run history tests with GCC and not with Clang is because Clang 51# already runs slower as a result of running with sanitizers, and the history 52# tests are a little sensitive to load on a system. 53# 54# If this script fails on any platform when starting the Karatsuba test, check 55# that Python is installed, especially if the error says something like: 56# "karatsuba.py: not found". 57 58# Print the usage and exit with an error. Each parameter should be an integer. 59# Non-zero activates, and zero deactivates. 60# @param 1 A message to print. 61usage() { 62 if [ $# -eq 1 ]; then 63 printf '%s\n\n' "$1" 64 fi 65 printf 'usage: %s [run_tests] [generate_tests] [run_problematic_tests] \n' "$script" 66 printf ' [test_with_clang] [test_with_gcc] [run_sanitizers] [run_valgrind] \n' 67 printf ' [test_settings] [run_64_bit] [run_gen_script] [test_c11] \n' 68 printf ' [test_128_bit] [test_computed_goto] [test_karatsuba] [test_history] \n' 69 printf ' [test_editline] [test_readline]\n' 70 exit 1 71} 72 73# Print a header with a message. This is just to make it easy to track progress. 74# @param msg The message to print in the header. 75header() { 76 77 _header_msg="$1" 78 shift 79 80 printf '\n' 81 printf '*******************\n' 82 printf "$_header_msg" 83 printf '\n' 84 printf '*******************\n' 85 printf '\n' 86} 87 88# Easy way to call make. 89do_make() { 90 # No reason to do 64 except to see if I actually can overload my system. :) 91 # Well, also that it might actually improve throughput as other jobs can run 92 # while some are waiting. 93 make -j64 "$@" 94} 95 96# Run configure.sh. 97# @param CFLAGS The CFLAGS. 98# @param CC The C compiler. 99# @param configure_flags The flags for configure.sh itself. 100# @param GEN_HOST The setting for GEN_HOST. 101# @param LONG_BIT The setting for LONG_BIT. 102configure() { 103 104 _configure_CFLAGS="$1" 105 shift 106 107 _configure_CC="$1" 108 shift 109 110 _configure_configure_flags="$1" 111 shift 112 113 _configure_GEN_HOST="$1" 114 shift 115 116 _configure_LONG_BIT="$1" 117 shift 118 119 # Make sure to not generate tests if necessary. 120 if [ "$gen_tests" -eq 0 ]; then 121 _configure_configure_flags="-G $_configure_configure_flags" 122 fi 123 124 # Make sure to skip problematic tests if necessary. 125 if [ "$problematic_tests" -eq 0 ]; then 126 _configure_configure_flags="-P $_configure_configure_flags" 127 fi 128 129 # Choose the right extra flags. 130 if [ "$_configure_CC" = "clang" ]; then 131 132 _configure_CFLAGS="$clang_flags $_configure_CFLAGS" 133 134 # We need to quiet this warning from Clang because the configure.sh docs 135 # have this warning, so people should know. Also, I want this script to 136 # work. 137 if [ "$_configure_GEN_HOST" -eq 0 ]; then 138 _configure_CFLAGS="$_configure_CFLAGS -Wno-overlength-strings" 139 fi 140 141 elif [ "$_configure_CC" = "gcc" ]; then 142 143 _configure_CFLAGS="$gcc_flags $_configure_CFLAGS" 144 145 # We need to quiet this warning from GCC because the configure.sh docs 146 # have this warning, so people should know. Also, I want this script to 147 # work. 148 if [ "$_configure_GEN_HOST" -eq 0 ]; then 149 _configure_CFLAGS="$_configure_CFLAGS -Wno-overlength-strings" 150 fi 151 152 fi 153 154 # Print the header and do the job. 155 _configure_header=$(printf 'Running configure.sh %s ...' "$_configure_configure_flags") 156 _configure_header=$(printf "$_configure_header\n CC=\"%s\"\n" "$_configure_CC") 157 _configure_header=$(printf "$_configure_header\n CFLAGS=\"%s\"\n" "$_configure_CFLAGS") 158 _configure_header=$(printf "$_configure_header\n LONG_BIT=%s" "$_configure_LONG_BIT") 159 _configure_header=$(printf "$_configure_header\n GEN_HOST=%s" "$_configure_GEN_HOST") 160 161 header "$_configure_header" 162 CFLAGS="$_configure_CFLAGS" CC="$_configure_CC" GEN_HOST="$_configure_GEN_HOST" \ 163 LONG_BIT="$_configure_LONG_BIT" "$real/configure.sh" $_configure_configure_flags > /dev/null 2> /dev/null 164} 165 166# Build with make. This function also captures and outputs any warnings if they 167# exists because as far as I am concerned, warnings are not acceptable for 168# release. 169# @param CFLAGS The CFLAGS. 170# @param CC The C compiler. 171# @param configure_flags The flags for configure.sh itself. 172# @param GEN_HOST The setting for GEN_HOST. 173# @param LONG_BIT The setting for LONG_BIT. 174build() { 175 176 _build_CFLAGS="$1" 177 shift 178 179 _build_CC="$1" 180 shift 181 182 _build_configure_flags="$1" 183 shift 184 185 _build_GEN_HOST="$1" 186 shift 187 188 _build_LONG_BIT="$1" 189 shift 190 191 configure "$_build_CFLAGS" "$_build_CC" "$_build_configure_flags" "$_build_GEN_HOST" "$_build_LONG_BIT" 192 193 _build_header=$(printf 'Building...\n CC=%s' "$_build_CC") 194 _build_header=$(printf "$_build_header\n CFLAGS=\"%s\"" "$_build_CFLAGS") 195 _build_header=$(printf "$_build_header\n LONG_BIT=%s" "$_build_LONG_BIT") 196 _build_header=$(printf "$_build_header\n GEN_HOST=%s" "$_build_GEN_HOST") 197 198 header "$_build_header" 199 200 set +e 201 202 # Capture and print warnings. 203 do_make > /dev/null 2> "./.test.txt" 204 err=$? 205 206 set -e 207 208 if [ -s "./.test.txt" ]; then 209 printf '%s generated warning(s):\n' "$_build_CC" 210 printf '\n' 211 cat "./.test.txt" 212 exit 1 213 fi 214 215 if [ "$err" -ne 0 ]; then 216 exit "$err" 217 fi 218} 219 220# Run tests with make. 221runtest() { 222 223 header "Running tests" 224 225 if [ "$#" -gt 0 ]; then 226 do_make "$@" 227 else 228 229 do_make test 230 231 if [ "$test_history" -ne 0 ]; then 232 do_make test_history 233 fi 234 fi 235} 236 237# Builds and runs tests with both calculators, then bc only, then dc only. If 238# run_tests is false, then it just does the builds. 239# @param CFLAGS The CFLAGS. 240# @param CC The C compiler. 241# @param configure_flags The flags for configure.sh itself. 242# @param GEN_HOST The setting for GEN_HOST. 243# @param LONG_BIT The setting for LONG_BIT. 244# @param run_tests Whether to run tests or not. 245runconfigtests() { 246 247 _runconfigtests_CFLAGS="$1" 248 shift 249 250 _runconfigtests_CC="$1" 251 shift 252 253 _runconfigtests_configure_flags="$1" 254 shift 255 256 _runconfigtests_GEN_HOST="$1" 257 shift 258 259 _runconfigtests_LONG_BIT="$1" 260 shift 261 262 _runconfigtests_run_tests="$1" 263 shift 264 265 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 266 _runconfigtests_header=$(printf 'Running tests with configure flags') 267 else 268 _runconfigtests_header=$(printf 'Building with configure flags') 269 fi 270 271 _runconfigtests_header=$(printf "$_runconfigtests_header \"%s\" ...\n" "$_runconfigtests_configure_flags") 272 _runconfigtests_header=$(printf "$_runconfigtests_header\n CC=%s\n" "$_runconfigseries_CC") 273 _runconfigtests_header=$(printf "$_runconfigtests_header\n CFLAGS=\"%s\"" "$_runconfigseries_CFLAGS") 274 _runconfigtests_header=$(printf "$_runconfigtests_header\n LONG_BIT=%s" "$_runconfigtests_LONG_BIT") 275 _runconfigtests_header=$(printf "$_runconfigtests_header\n GEN_HOST=%s" "$_runconfigtests_GEN_HOST") 276 277 header "$_runconfigtests_header" 278 279 build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ 280 "$_runconfigtests_configure_flags" "$_runconfigtests_GEN_HOST" \ 281 "$_runconfigtests_LONG_BIT" 282 283 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 284 runtest 285 fi 286 287 do_make clean 288 289 build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ 290 "$_runconfigtests_configure_flags -b" "$_runconfigtests_GEN_HOST" \ 291 "$_runconfigtests_LONG_BIT" 292 293 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 294 runtest 295 fi 296 297 do_make clean 298 299 build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ 300 "$_runconfigtests_configure_flags -d" "$_runconfigtests_GEN_HOST" \ 301 "$_runconfigtests_LONG_BIT" 302 303 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 304 runtest 305 fi 306 307 do_make clean 308} 309 310# Builds and runs tests with runconfigtests(), but also does 64-bit, 32-bit, and 311# 128-bit rand, if requested. It also does it with the gen script (strgen.sh) if 312# requested. If run_tests is false, it just does the builds. 313# @param CFLAGS The CFLAGS. 314# @param CC The C compiler. 315# @param configure_flags The flags for configure.sh itself. 316# @param run_tests Whether to run tests or not. 317runconfigseries() { 318 319 _runconfigseries_CFLAGS="$1" 320 shift 321 322 _runconfigseries_CC="$1" 323 shift 324 325 _runconfigseries_configure_flags="$1" 326 shift 327 328 _runconfigseries_run_tests="$1" 329 shift 330 331 if [ "$run_64_bit" -ne 0 ]; then 332 333 if [ "$test_128_bit" -ne 0 ]; then 334 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 335 "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" 336 fi 337 338 if [ "$run_gen_script" -ne 0 ]; then 339 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 340 "$_runconfigseries_configure_flags" 0 64 "$_runconfigseries_run_tests" 341 fi 342 343 runconfigtests "$_runconfigseries_CFLAGS -DBC_RAND_BUILTIN=0" "$_runconfigseries_CC" \ 344 "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" 345 346 # Test Editline and Readline if history is not turned off. 347 if [ "${_runconfigseries_configure_flags#*H}" = "${_runconfigseries_configure_flags}" ]; then 348 349 if [ "$test_editline" -ne 0 ]; then 350 runconfigtests "$_runconfigseries_CFLAGS -DBC_RAND_BUILTIN=0" "$_runconfigseries_CC" \ 351 "$_runconfigseries_configure_flags -e" 1 64 "$_runconfigseries_run_tests" 352 fi 353 354 if [ "$test_readline" -ne 0 ]; then 355 runconfigtests "$_runconfigseries_CFLAGS -DBC_RAND_BUILTIN=0" "$_runconfigseries_CC" \ 356 "$_runconfigseries_configure_flags -r" 1 64 "$_runconfigseries_run_tests" 357 fi 358 359 fi 360 361 fi 362 363 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 364 "$_runconfigseries_configure_flags" 1 32 "$_runconfigseries_run_tests" 365 366 if [ "$run_gen_script" -ne 0 ]; then 367 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 368 "$_runconfigseries_configure_flags" 0 32 "$_runconfigseries_run_tests" 369 fi 370} 371 372# Builds and runs tests with each setting combo running runconfigseries(). If 373# run_tests is false, it just does the builds. 374# @param CFLAGS The CFLAGS. 375# @param CC The C compiler. 376# @param configure_flags The flags for configure.sh itself. 377# @param run_tests Whether to run tests or not. 378runsettingsseries() { 379 380 _runsettingsseries_CFLAGS="$1" 381 shift 382 383 _runsettingsseries_CC="$1" 384 shift 385 386 _runsettingsseries_configure_flags="$1" 387 shift 388 389 _runsettingsseries_run_tests="$1" 390 shift 391 392 if [ "$test_settings" -ne 0 ]; then 393 394 while read _runsettingsseries_s; do 395 runconfigseries "$_runsettingsseries_CFLAGS" "$_runsettingsseries_CC" \ 396 "$_runsettingsseries_configure_flags $_runsettingsseries_s" \ 397 "$_runsettingsseries_run_tests" 398 done < "$scriptdir/release_settings.txt" 399 400 else 401 runconfigseries "$_runsettingsseries_CFLAGS" "$_runsettingsseries_CC" \ 402 "$_runsettingsseries_configure_flags" "$_runsettingsseries_run_tests" 403 fi 404} 405 406# Builds and runs tests with each build type running runsettingsseries(). If 407# run_tests is false, it just does the builds. 408# @param CFLAGS The CFLAGS. 409# @param CC The C compiler. 410# @param configure_flags The flags for configure.sh itself. 411# @param run_tests Whether to run tests or not. 412runtestseries() { 413 414 _runtestseries_CFLAGS="$1" 415 shift 416 417 _runtestseries_CC="$1" 418 shift 419 420 _runtestseries_configure_flags="$1" 421 shift 422 423 _runtestseries_run_tests="$1" 424 shift 425 426 _runtestseries_flags="E H N EH EN HN EHN" 427 428 runsettingsseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ 429 "$_runtestseries_configure_flags" "$_runtestseries_run_tests" 430 431 for _runtestseries_f in $_runtestseries_flags; do 432 runsettingsseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ 433 "$_runtestseries_configure_flags -$_runtestseries_f" "$_runtestseries_run_tests" 434 done 435} 436 437# Builds and runs the tests for bcl. If run_tests is false, it just does the 438# builds. 439# @param CFLAGS The CFLAGS. 440# @param CC The C compiler. 441# @param configure_flags The flags for configure.sh itself. 442# @param run_tests Whether to run tests or not. 443runlibtests() { 444 445 _runlibtests_CFLAGS="$1" 446 shift 447 448 _runlibtests_CC="$1" 449 shift 450 451 _runlibtests_configure_flags="$1" 452 shift 453 454 _runlibtests_run_tests="$1" 455 shift 456 457 _runlibtests_configure_flags="$_runlibtests_configure_flags -a" 458 459 build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 64 460 461 if [ "$_runlibtests_run_tests" -ne 0 ]; then 462 runtest test 463 fi 464 465 build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 32 466 467 if [ "$_runlibtests_run_tests" -ne 0 ]; then 468 runtest test 469 fi 470} 471 472# Builds and runs tests under C99, then C11, if requested, using 473# runtestseries(). If run_tests is false, it just does the builds. 474# @param CFLAGS The CFLAGS. 475# @param CC The C compiler. 476# @param configure_flags The flags for configure.sh itself. 477# @param run_tests Whether to run tests or not. 478runtests() { 479 480 _runtests_CFLAGS="$1" 481 shift 482 483 _runtests_CC="$1" 484 shift 485 486 _runtests_configure_flags="$1" 487 shift 488 489 _runtests_run_tests="$1" 490 shift 491 492 runtestseries "-std=c99 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" 493 494 if [ "$test_c11" -ne 0 ]; then 495 runtestseries "-std=c11 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" 496 fi 497} 498 499# Runs the karatsuba tests. 500karatsuba() { 501 502 header "Running Karatsuba tests" 503 do_make karatsuba_test 504} 505 506# Builds and runs under valgrind. It runs both, bc only, then dc only. 507vg() { 508 509 header "Running valgrind" 510 511 if [ "$run_64_bit" -ne 0 ]; then 512 _vg_bits=64 513 else 514 _vg_bits=32 515 fi 516 517 build "$debug -std=c99" "gcc" "-O3 -gv" "1" "$_vg_bits" 518 runtest test 519 520 do_make clean_config 521 522 build "$debug -std=c99" "gcc" "-O3 -gvb" "1" "$_vg_bits" 523 runtest test 524 525 do_make clean_config 526 527 build "$debug -std=c99" "gcc" "-O3 -gvd" "1" "$_vg_bits" 528 runtest test 529 530 do_make clean_config 531 532 build "$debug -std=c99" "gcc" "-O3 -gva" "1" "$_vg_bits" 533 runtest test 534 535 do_make clean_config 536} 537 538# Builds the debug series and runs the tests if run_tests allows. If sanitizers 539# are enabled, it also does UBSan. 540# @param CC The C compiler. 541# @param run_tests Whether to run tests or not. 542debug() { 543 544 _debug_CC="$1" 545 shift 546 547 _debug_run_tests="$1" 548 shift 549 550 551 if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 552 runtests "$debug -fsanitize=undefined" "$_debug_CC" "-gm" "$_debug_run_tests" 553 else 554 runtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests" 555 fi 556 557 if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 558 runlibtests "$debug -fsanitize=undefined" "$_debug_CC" "-gm" "$_debug_run_tests" 559 else 560 runlibtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests" 561 fi 562} 563 564# Builds the release series and runs the test if run_tests allows. 565# @param CC The C compiler. 566# @param run_tests Whether to run tests or not. 567release() { 568 569 _release_CC="$1" 570 shift 571 572 _release_run_tests="$1" 573 shift 574 575 runtests "$release" "$_release_CC" "-O3" "$_release_run_tests" 576 577 runlibtests "$release" "$_release_CC" "-O3" "$_release_run_tests" 578} 579 580# Builds the release debug series and runs the test if run_tests allows. If 581# sanitizers are enabled, it also does ASan and MSan. 582# @param CC The C compiler. 583# @param run_tests Whether to run tests or not. 584reldebug() { 585 586 _reldebug_CC="$1" 587 shift 588 589 _reldebug_run_tests="$1" 590 shift 591 592 593 if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 594 runtests "$debug -fsanitize=address" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" 595 runtests "$debug -fsanitize=memory" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" 596 else 597 runtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 598 fi 599 600 601 if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 602 runlibtests "$debug -fsanitize=address" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" 603 runlibtests "$debug -fsanitize=memory" "$_reldebug_CC" "-mgO3" "$_reldebug_run_tests" 604 else 605 runlibtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 606 fi 607} 608 609# Builds the min size release series and runs the test if run_tests allows. 610# @param CC The C compiler. 611# @param run_tests Whether to run tests or not. 612minsize() { 613 614 _minsize_CC="$1" 615 shift 616 617 _minsize_run_tests="$1" 618 shift 619 620 runtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests" 621 622 runlibtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests" 623} 624 625# Builds all sets: debug, release, release debug, and min size, and runs the 626# tests if run_tests allows. 627# @param CC The C compiler. 628# @param run_tests Whether to run tests or not. 629build_set() { 630 631 _build_set_CC="$1" 632 shift 633 634 _build_set_run_tests="$1" 635 shift 636 637 debug "$_build_set_CC" "$_build_set_run_tests" 638 release "$_build_set_CC" "$_build_set_run_tests" 639 reldebug "$_build_set_CC" "$_build_set_run_tests" 640 minsize "$_build_set_CC" "$_build_set_run_tests" 641} 642 643set -e 644 645script="$0" 646scriptdir=$(dirname "$script") 647 648. "$scriptdir/functions.sh" 649 650# Unset all bc and dc environment variables. This is intended to allow this 651# script to run in a clean environment. 652unset POSIXLY_CORRECT 653unset BC_BANNER 654unset BC_ENV_ARGS 655unset DC_ENV_ARGS 656unset BC_LINE_LENGTH 657unset DC_LINE_LENGTH 658unset BC_SIGINT_RESET 659unset DC_SIGINT_RESET 660unset BC_TTY_MODE 661unset DC_TTY_MODE 662unset BC_PROMPT 663unset DC_PROMPT 664unset BC_EXPR_EXIT 665unset DC_EXPR_EXIT 666unset BC_DIGIT_CLAMP 667unset DC_DIGIT_CLAMP 668 669os=$(uname) 670# Set some strict warning flags. Clang's -Weverything can be way too strict, so 671# we actually have to turn off some things. 672clang_flags="-Weverything -Wno-padded -Wno-unsafe-buffer-usage -Wno-poison-system-directories -Wno-switch-default" 673gcc_flags="-Wno-clobbered" 674 675# Common CFLAGS. 676cflags="-Wall -Wextra -Werror -pedantic" 677 678# Common debug and release flags. 679debug="$cflags -fno-omit-frame-pointer" 680release="$cflags -DNDEBUG" 681 682real=$(realpath "$scriptdir/../") 683 684# Whether to run tests. 685if [ "$#" -gt 0 ]; then 686 run_tests="$1" 687 shift 688 check_bool_arg "$run_tests" 689else 690 run_tests=1 691 check_bool_arg "$run_tests" 692fi 693 694# Whether to generate tests. On platforms like OpenBSD, there is no GNU bc to 695# generate tests, so this must be off. 696if [ "$#" -gt 0 ]; then 697 gen_tests="$1" 698 shift 699 check_bool_arg "$gen_tests" 700else 701 gen_tests=1 702 check_bool_arg "$gen_tests" 703fi 704 705# Whether to run problematic tests. This needs to be off on FreeBSD. 706if [ "$#" -gt 0 ]; then 707 problematic_tests="$1" 708 shift 709 check_bool_arg "$problematic_tests" 710else 711 problematic_tests=1 712 check_bool_arg "$problematic_tests" 713fi 714 715# Whether to test with clang. 716if [ "$#" -gt 0 ]; then 717 test_with_clang="$1" 718 shift 719 check_bool_arg "$test_with_clang" 720else 721 test_with_clang=1 722 check_bool_arg "$test_with_clang" 723fi 724 725# Whether to test with gcc. 726if [ "$#" -gt 0 ]; then 727 test_with_gcc="$1" 728 shift 729 check_bool_arg "$test_with_gcc" 730else 731 test_with_gcc=1 732 check_bool_arg "$test_with_clang" 733fi 734 735# Whether to test with sanitizers. 736if [ "$#" -gt 0 ]; then 737 run_sanitizers="$1" 738 check_bool_arg "$run_sanitizers" 739 shift 740else 741 run_sanitizers=1 742 check_bool_arg "$run_sanitizers" 743fi 744 745# Whether to test with valgrind. 746if [ "$#" -gt 0 ]; then 747 run_valgrind="$1" 748 shift 749 check_bool_arg "$run_valgrind" 750else 751 run_valgrind=1 752 check_bool_arg "$run_valgrind" 753fi 754 755# Whether to test all settings combos. 756if [ "$#" -gt 0 ]; then 757 test_settings="$1" 758 shift 759 check_bool_arg "$test_settings" 760else 761 test_settings=1 762 check_bool_arg "$test_settings" 763fi 764 765# Whether to test 64-bit in addition to 32-bit. 766if [ "$#" -gt 0 ]; then 767 run_64_bit="$1" 768 shift 769 check_bool_arg "$run_64_bit" 770else 771 run_64_bit=1 772 check_bool_arg "$run_64_bit" 773fi 774 775# Whether to test with strgen.sh in addition to strgen.c. 776if [ "$#" -gt 0 ]; then 777 run_gen_script="$1" 778 shift 779 check_bool_arg "$run_gen_script" 780else 781 run_gen_script=0 782 check_bool_arg "$run_gen_script" 783fi 784 785# Whether to test on C11 in addition to C99. 786if [ "$#" -gt 0 ]; then 787 test_c11="$1" 788 shift 789 check_bool_arg "$test_c11" 790else 791 test_c11=0 792 check_bool_arg "$test_c11" 793fi 794 795# Whether to test 128-bit integers in addition to no 128-bit integers. 796if [ "$#" -gt 0 ]; then 797 test_128_bit="$1" 798 shift 799 check_bool_arg "$test_128_bit" 800else 801 test_128_bit=0 802 check_bool_arg "$test_128_bit" 803fi 804 805# Whether to test with computed goto or not. 806if [ "$#" -gt 0 ]; then 807 test_computed_goto="$1" 808 shift 809 check_bool_arg "$test_computed_goto" 810else 811 test_computed_goto=0 812 check_bool_arg "$test_computed_goto" 813fi 814 815# Whether to test history or not. 816if [ "$#" -gt 0 ]; then 817 test_karatsuba="$1" 818 shift 819 check_bool_arg "$test_karatsuba" 820else 821 test_karatsuba=1 822 check_bool_arg "$test_karatsuba" 823fi 824 825# Whether to test history or not. 826if [ "$#" -gt 0 ]; then 827 test_history="$1" 828 shift 829 check_bool_arg "$test_history" 830else 831 test_history=0 832 check_bool_arg "$test_history" 833fi 834 835# Whether to test editline or not. 836if [ "$#" -gt 0 ]; then 837 test_editline="$1" 838 shift 839 check_bool_arg "$test_editline" 840else 841 test_editline=0 842 check_bool_arg "$test_editline" 843fi 844 845# Whether to test editline or not. 846if [ "$#" -gt 0 ]; then 847 test_readline="$1" 848 shift 849 check_bool_arg "$test_readline" 850else 851 test_readline=0 852 check_bool_arg "$test_readline" 853fi 854 855if [ "$run_64_bit" -ne 0 ]; then 856 bits=64 857else 858 bits=32 859fi 860 861if [ "$test_computed_goto" -eq 0 ]; then 862 clang_flags="-DBC_NO_COMPUTED_GOTO $clang_flags" 863 gcc_flags="-DBC_NO_COMPUTED_GOTO $gcc_flags" 864fi 865 866# Setup a default compiler. 867if [ "$test_with_clang" -ne 0 ]; then 868 defcc="clang" 869elif [ "$test_with_gcc" -ne 0 ]; then 870 defcc="gcc" 871else 872 defcc="c99" 873fi 874 875export 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" 876export UBSAN_OPTIONS="print_stack_trace=1,silence_unsigned_overflow=1" 877 878build "$debug -std=c99" "$defcc" "-g" "1" "$bits" 879 880header "Running math library under --standard" 881 882# Make sure the math library is POSIX compliant. 883printf 'quit\n' | bin/bc -ls 884 885do_make clean_tests 886 887# Run the clang build sets. 888if [ "$test_with_clang" -ne 0 ]; then 889 build_set "clang" "$run_tests" 890fi 891 892# Run the gcc build sets. 893if [ "$test_with_gcc" -ne 0 ]; then 894 build_set "gcc" "$run_tests" 895fi 896 897if [ "$run_tests" -ne 0 ]; then 898 899 build "$release" "$defcc" "-O3" "1" "$bits" 900 901 # Run karatsuba. 902 if [ "$test_karatsuba" -ne 0 ]; then 903 karatsuba 904 fi 905 906 # Valgrind. 907 if [ "$run_valgrind" -ne 0 -a "$test_with_gcc" -ne 0 ]; then 908 vg 909 fi 910 911 printf '\n' 912 printf 'Tests successful.\n' 913 914fi 915