1#! /bin/sh 2# 3# SPDX-License-Identifier: BSD-2-Clause 4# 5# Copyright (c) 2018-2021 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 30script="$0" 31scriptdir=$(dirname "$script") 32script=$(basename "$script") 33 34. "$scriptdir/scripts/functions.sh" 35 36cd "$scriptdir" 37 38# Simply prints the help message and quits based on the argument. 39# @param val The value to pass to exit. Must be an integer. 40usage() { 41 42 if [ $# -gt 0 ]; then 43 44 _usage_val=1 45 46 printf "%s\n\n" "$1" 47 48 else 49 _usage_val=0 50 fi 51 52 printf 'usage:\n' 53 printf ' %s -h\n' "$script" 54 printf ' %s --help\n' "$script" 55 printf ' %s [-a|-bD|-dB|-c] [-CEfgGHlmMNPtTvz] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\n' "$script" 56 printf ' %s \\\n' "$script" 57 printf ' [--library|--bc-only --disable-dc|--dc-only --disable-bc|--coverage] \\\n' 58 printf ' [--force --debug --disable-extra-math --disable-generated-tests] \\\n' 59 printf ' [--disable-history --disable-man-pages --disable-nls --disable-strip] \\\n' 60 printf ' [--install-all-locales] [--opt=OPT_LEVEL] \\\n' 61 printf ' [--karatsuba-len=KARATSUBA_LEN] \\\n' 62 printf ' [--prefix=PREFIX] [--bindir=BINDIR] [--datarootdir=DATAROOTDIR] \\\n' 63 printf ' [--datadir=DATADIR] [--mandir=MANDIR] [--man1dir=MAN1DIR] \\\n' 64 printf '\n' 65 printf ' -a, --library\n' 66 printf ' Build the libbcl instead of the programs. This is meant to be used with\n' 67 printf ' Other software like programming languages that want to make use of the\n' 68 printf ' parsing and math capabilities. This option will install headers using\n' 69 printf ' `make install`.\n' 70 printf ' -b, --bc-only\n' 71 printf ' Build bc only. It is an error if "-d", "--dc-only", "-B", or\n' 72 printf ' "--disable-bc" are specified too.\n' 73 printf ' -B, --disable-bc\n' 74 printf ' Disable bc. It is an error if "-b", "--bc-only", "-D", or "--disable-dc"\n' 75 printf ' are specified too.\n' 76 printf ' -c, --coverage\n' 77 printf ' Generate test coverage code. Requires gcov and gcovr.\n' 78 printf ' It is an error if either "-b" ("-D") or "-d" ("-B") is specified.\n' 79 printf ' Requires a compiler that use gcc-compatible coverage options\n' 80 printf ' -C, --disable-clean\n' 81 printf ' Disable the clean that configure.sh does before configure.\n' 82 printf ' -d, --dc-only\n' 83 printf ' Build dc only. It is an error if "-b", "--bc-only", "-D", or\n' 84 printf ' "--disable-dc" are specified too.\n' 85 printf ' -D, --disable-dc\n' 86 printf ' Disable dc. It is an error if "-d", "--dc-only", "-B", or "--disable-bc"\n' 87 printf ' are specified too.\n' 88 printf ' -E, --disable-extra-math\n' 89 printf ' Disable extra math. This includes: "$" operator (truncate to integer),\n' 90 printf ' "@" operator (set number of decimal places), and r(x, p) (rounding\n' 91 printf ' function). Additionally, this option disables the extra printing\n' 92 printf ' functions in the math library.\n' 93 printf ' -f, --force\n' 94 printf ' Force use of all enabled options, even if they do not work. This\n' 95 printf ' option is to allow the maintainer a way to test that certain options\n' 96 printf ' are not failing invisibly. (Development only.)' 97 printf ' -g, --debug\n' 98 printf ' Build in debug mode. Adds the "-g" flag, and if there are no\n' 99 printf ' other CFLAGS, and "-O" was not given, this also adds the "-O0"\n' 100 printf ' flag. If this flag is *not* given, "-DNDEBUG" is added to CPPFLAGS\n' 101 printf ' and a strip flag is added to the link stage.\n' 102 printf ' -G, --disable-generated-tests\n' 103 printf ' Disable generating tests. This is for platforms that do not have a\n' 104 printf ' GNU bc-compatible bc to generate tests.\n' 105 printf ' -h, --help\n' 106 printf ' Print this help message and exit.\n' 107 printf ' -H, --disable-history\n' 108 printf ' Disable history.\n' 109 printf ' -k KARATSUBA_LEN, --karatsuba-len KARATSUBA_LEN\n' 110 printf ' Set the karatsuba length to KARATSUBA_LEN (default is 64).\n' 111 printf ' It is an error if KARATSUBA_LEN is not a number or is less than 16.\n' 112 printf ' -l, --install-all-locales\n' 113 printf ' Installs all locales, regardless of how many are on the system. This\n' 114 printf ' option is useful for package maintainers who want to make sure that\n' 115 printf ' a package contains all of the locales that end users might need.\n' 116 printf ' -m, --enable-memcheck\n' 117 printf ' Enable memcheck mode, to ensure no memory leaks. For development only.\n' 118 printf ' -M, --disable-man-pages\n' 119 printf ' Disable installing manpages.\n' 120 printf ' -N, --disable-nls\n' 121 printf ' Disable POSIX locale (NLS) support.\n' 122 printf ' -O OPT_LEVEL, --opt OPT_LEVEL\n' 123 printf ' Set the optimization level. This can also be included in the CFLAGS,\n' 124 printf ' but it is provided, so maintainers can build optimized debug builds.\n' 125 printf ' This is passed through to the compiler, so it must be supported.\n' 126 printf ' -s SETTING, --set-default-on SETTING\n' 127 printf ' Set the default named by SETTING to on. See below for possible values\n' 128 printf ' for SETTING. For multiple instances of the -s or -S for the the same\n' 129 printf ' setting, the last one is used.\n' 130 printf ' -S SETTING, --set-default-off SETTING\n' 131 printf ' Set the default named by SETTING to off. See below for possible values\n' 132 printf ' for SETTING. For multiple instances of the -s or -S for the the same\n' 133 printf ' setting, the last one is used.\n' 134 printf ' -t, --enable-test-timing\n' 135 printf ' Enable the timing of tests. This is for development only.\n' 136 printf ' -T, --disable-strip\n' 137 printf ' Disable stripping symbols from the compiled binary or binaries.\n' 138 printf ' Stripping symbols only happens when debug mode is off.\n' 139 printf ' -v, --enable-valgrind\n' 140 printf ' Enable a build appropriate for valgrind. For development only.\n' 141 printf ' -z, --enable-fuzz-mode\n' 142 printf ' Enable fuzzing mode. THIS IS FOR DEVELOPMENT ONLY.\n' 143 printf ' --prefix PREFIX\n' 144 printf ' The prefix to install to. Overrides "$PREFIX" if it exists.\n' 145 printf ' If PREFIX is "/usr", install path will be "/usr/bin".\n' 146 printf ' Default is "/usr/local".\n' 147 printf ' --bindir BINDIR\n' 148 printf ' The directory to install binaries in. Overrides "$BINDIR" if it exists.\n' 149 printf ' Default is "$PREFIX/bin".\n' 150 printf ' --includedir INCLUDEDIR\n' 151 printf ' The directory to install headers in. Overrides "$INCLUDEDIR" if it\n' 152 printf ' exists. Default is "$PREFIX/include".\n' 153 printf ' --libdir LIBDIR\n' 154 printf ' The directory to install libraries in. Overrides "$LIBDIR" if it exists.\n' 155 printf ' Default is "$PREFIX/lib".\n' 156 printf ' --datarootdir DATAROOTDIR\n' 157 printf ' The root location for data files. Overrides "$DATAROOTDIR" if it exists.\n' 158 printf ' Default is "$PREFIX/share".\n' 159 printf ' --datadir DATADIR\n' 160 printf ' The location for data files. Overrides "$DATADIR" if it exists.\n' 161 printf ' Default is "$DATAROOTDIR".\n' 162 printf ' --mandir MANDIR\n' 163 printf ' The location to install manpages to. Overrides "$MANDIR" if it exists.\n' 164 printf ' Default is "$DATADIR/man".\n' 165 printf ' --man1dir MAN1DIR\n' 166 printf ' The location to install Section 1 manpages to. Overrides "$MAN1DIR" if\n' 167 printf ' it exists. Default is "$MANDIR/man1".\n' 168 printf ' --man3dir MAN3DIR\n' 169 printf ' The location to install Section 3 manpages to. Overrides "$MAN3DIR" if\n' 170 printf ' it exists. Default is "$MANDIR/man3".\n' 171 printf '\n' 172 printf 'In addition, the following environment variables are used:\n' 173 printf '\n' 174 printf ' CC C compiler. Must be compatible with POSIX c99. If there is a\n' 175 printf ' space in the basename of the compiler, the items after the\n' 176 printf ' first space are assumed to be compiler flags, and in that case,\n' 177 printf ' the flags are automatically moved into CFLAGS. Default is\n' 178 printf ' "c99".\n' 179 printf ' HOSTCC Host C compiler. Must be compatible with POSIX c99. If there is\n' 180 printf ' a space in the basename of the compiler, the items after the\n' 181 printf ' first space are assumed to be compiler flags, and in the case,\n' 182 printf ' the flags are automatically moved into HOSTCFLAGS. Default is\n' 183 printf ' "$CC".\n' 184 printf ' HOST_CC Same as HOSTCC. If HOSTCC also exists, it is used.\n' 185 printf ' CFLAGS C compiler flags.\n' 186 printf ' HOSTCFLAGS CFLAGS for HOSTCC. Default is "$CFLAGS".\n' 187 printf ' HOST_CFLAGS Same as HOST_CFLAGS. If HOST_CFLAGS also exists, it is used.\n' 188 printf ' CPPFLAGS C preprocessor flags. Default is "".\n' 189 printf ' LDFLAGS Linker flags. Default is "".\n' 190 printf ' PREFIX The prefix to install to. Default is "/usr/local".\n' 191 printf ' If PREFIX is "/usr", install path will be "/usr/bin".\n' 192 printf ' BINDIR The directory to install binaries in. Default is "$PREFIX/bin".\n' 193 printf ' INCLUDEDIR The directory to install header files in. Default is\n' 194 printf ' "$PREFIX/include".\n' 195 printf ' LIBDIR The directory to install libraries in. Default is\n' 196 printf ' "$PREFIX/lib".\n' 197 printf ' DATAROOTDIR The root location for data files. Default is "$PREFIX/share".\n' 198 printf ' DATADIR The location for data files. Default is "$DATAROOTDIR".\n' 199 printf ' MANDIR The location to install manpages to. Default is "$DATADIR/man".\n' 200 printf ' MAN1DIR The location to install Section 1 manpages to. Default is\n' 201 printf ' "$MANDIR/man1".\n' 202 printf ' MAN3DIR The location to install Section 3 manpages to. Default is\n' 203 printf ' "$MANDIR/man3".\n' 204 printf ' NLSPATH The location to install locale catalogs to. Must be an absolute\n' 205 printf ' path (or contain one). This is treated the same as the POSIX\n' 206 printf ' definition of $NLSPATH (see POSIX environment variables for\n' 207 printf ' more information). Default is "/usr/share/locale/%%L/%%N".\n' 208 printf ' EXECSUFFIX The suffix to append to the executable names, used to not\n' 209 printf ' interfere with other installed bc executables. Default is "".\n' 210 printf ' EXECPREFIX The prefix to append to the executable names, used to not\n' 211 printf ' interfere with other installed bc executables. Default is "".\n' 212 printf ' DESTDIR For package creation. Default is "". If it is empty when\n' 213 printf ' `%s` is run, it can also be passed to `make install`\n' "$script" 214 printf ' later as an environment variable. If both are specified,\n' 215 printf ' the one given to `%s` takes precedence.\n' "$script" 216 printf ' LONG_BIT The number of bits in a C `long` type. This is mostly for the\n' 217 printf ' embedded space since this `bc` uses `long`s internally for\n' 218 printf ' overflow checking. In C99, a `long` is required to be 32 bits.\n' 219 printf ' For most normal desktop systems, setting this is unnecessary,\n' 220 printf ' except that 32-bit platforms with 64-bit longs may want to set\n' 221 printf ' it to `32`. Default is the default of `LONG_BIT` for the target\n' 222 printf ' platform. Minimum allowed is `32`. It is a build time error if\n' 223 printf ' the specified value of `LONG_BIT` is greater than the default\n' 224 printf ' value of `LONG_BIT` for the target platform.\n' 225 printf ' GEN_HOST Whether to use `gen/strgen.c`, instead of `gen/strgen.sh`, to\n' 226 printf ' produce the C files that contain the help texts as well as the\n' 227 printf ' math libraries. By default, `gen/strgen.c` is used, compiled by\n' 228 printf ' "$HOSTCC" and run on the host machine. Using `gen/strgen.sh`\n' 229 printf ' removes the need to compile and run an executable on the host\n' 230 printf ' machine since `gen/strgen.sh` is a POSIX shell script. However,\n' 231 printf ' `gen/lib2.bc` is perilously close to 4095 characters, the max\n' 232 printf ' supported length of a string literal in C99 (and it could be\n' 233 printf ' added to in the future), and `gen/strgen.sh` generates a string\n' 234 printf ' literal instead of an array, as `gen/strgen.c` does. For most\n' 235 printf ' production-ready compilers, this limit probably is not\n' 236 printf ' enforced, but it could be. Both options are still available for\n' 237 printf ' this reason. If you are sure your compiler does not have the\n' 238 printf ' limit and do not want to compile and run a binary on the host\n' 239 printf ' machine, set this variable to "0". Any other value, or a\n' 240 printf ' non-existent value, will cause the build system to compile and\n' 241 printf ' run `gen/strgen.c`. Default is "".\n' 242 printf ' GEN_EMU Emulator to run string generator code under (leave empty if not\n' 243 printf ' necessary). This is not necessary when using `gen/strgen.sh`.\n' 244 printf ' Default is "".\n' 245 printf '\n' 246 printf 'WARNING: even though `configure.sh` supports both option types, short and\n' 247 printf 'long, it does not support handling both at the same time. Use only one type.\n' 248 printf '\n' 249 printf 'Settings\n' 250 printf '========\n' 251 printf '\n' 252 printf 'bc and dc have some settings that, while they cannot be removed by build time\n' 253 printf 'options, can have their defaults changed at build time by packagers. Users are\n' 254 printf 'also able to change each setting with environment variables.\n' 255 printf '\n' 256 printf 'The following is a table of settings, along with their default values and the\n' 257 printf 'environment variables users can use to change them. (For the defaults, non-zero\n' 258 printf 'means on, and zero means off.)\n' 259 printf '\n' 260 printf '| Setting | Description | Default | Env Variable |\n' 261 printf '| =============== | ==================== | ============ | ==================== |\n' 262 printf '| bc.banner | Whether to display | 0 | BC_BANNER |\n' 263 printf '| | the bc version | | |\n' 264 printf '| | banner when in | | |\n' 265 printf '| | interactive mode. | | |\n' 266 printf '| --------------- | -------------------- | ------------ | -------------------- |\n' 267 printf '| bc.sigint_reset | Whether SIGINT will | 1 | BC_SIGINT_RESET |\n' 268 printf '| | reset bc, instead of | | |\n' 269 printf '| | exiting, when in | | |\n' 270 printf '| | interactive mode. | | |\n' 271 printf '| --------------- | -------------------- | ------------ | -------------------- |\n' 272 printf '| dc.sigint_reset | Whether SIGINT will | 1 | DC_SIGINT_RESET |\n' 273 printf '| | reset dc, instead of | | |\n' 274 printf '| | exiting, when in | | |\n' 275 printf '| | interactive mode. | | |\n' 276 printf '| --------------- | -------------------- | ------------ | -------------------- |\n' 277 printf '| bc.tty_mode | Whether TTY mode for | 1 | BC_TTY_MODE |\n' 278 printf '| | bc should be on when | | |\n' 279 printf '| | available. | | |\n' 280 printf '| --------------- | -------------------- | ------------ | -------------------- |\n' 281 printf '| dc.tty_mode | Whether TTY mode for | 0 | BC_TTY_MODE |\n' 282 printf '| | dc should be on when | | |\n' 283 printf '| | available. | | |\n' 284 printf '| --------------- | -------------------- | ------------ | -------------------- |\n' 285 printf '| bc.prompt | Whether the prompt | $BC_TTY_MODE | BC_PROMPT |\n' 286 printf '| | for bc should be on | | |\n' 287 printf '| | in tty mode. | | |\n' 288 printf '| --------------- | -------------------- | ------------ | -------------------- |\n' 289 printf '| dc.prompt | Whether the prompt | $DC_TTY_MODE | DC_PROMPT |\n' 290 printf '| | for dc should be on | | |\n' 291 printf '| | in tty mode. | | |\n' 292 printf '| --------------- | -------------------- | ------------ | -------------------- |\n' 293 printf '\n' 294 printf 'These settings are not meant to be changed on a whim. They are meant to ensure\n' 295 printf 'that this bc and dc will conform to the expectations of the user on each\n' 296 printf 'platform.\n' 297 298 exit "$_usage_val" 299} 300 301# Replaces a file extension in a filename. This is used mostly to turn filenames 302# like `src/num.c` into `src/num.o`. In other words, it helps to link targets to 303# the files they depend on. 304# 305# @param file The filename. 306# @param ext1 The extension to replace. 307# @param ext2 The new extension. 308replace_ext() { 309 310 if [ "$#" -ne 3 ]; then 311 err_exit "Invalid number of args to $0" 312 fi 313 314 _replace_ext_file="$1" 315 _replace_ext_ext1="$2" 316 _replace_ext_ext2="$3" 317 318 _replace_ext_result="${_replace_ext_file%.$_replace_ext_ext1}.$_replace_ext_ext2" 319 320 printf '%s\n' "$_replace_ext_result" 321} 322 323# Replaces a file extension in every filename given in a list. The list is just 324# a space-separated list of words, so filenames are expected to *not* have 325# spaces in them. See the documentation for `replace_ext()`. 326# 327# @param files The list of space-separated filenames to replace extensions for. 328# @param ext1 The extension to replace. 329# @param ext2 The new extension. 330replace_exts() { 331 332 if [ "$#" -ne 3 ]; then 333 err_exit "Invalid number of args to $0" 334 fi 335 336 _replace_exts_files="$1" 337 _replace_exts_ext1="$2" 338 _replace_exts_ext2="$3" 339 340 for _replace_exts_file in $_replace_exts_files; do 341 _replace_exts_new_name=$(replace_ext "$_replace_exts_file" "$_replace_exts_ext1" "$_replace_exts_ext2") 342 _replace_exts_result="$_replace_exts_result $_replace_exts_new_name" 343 done 344 345 printf '%s\n' "$_replace_exts_result" 346} 347 348# Finds a placeholder in @a str and replaces it. This is the workhorse of 349# configure.sh. It's what replaces placeholders in Makefile.in with the data 350# needed for the chosen build. Below, you will see a lot of calls to this 351# function. 352# 353# Note that needle can never contain an exclamation point. For more information, 354# see substring_replace() in scripts/functions.sh. 355# 356# @param str The string to find and replace placeholders in. 357# @param needle The placeholder name. 358# @param replacement The string to use to replace the placeholder. 359replace() { 360 361 if [ "$#" -ne 3 ]; then 362 err_exit "Invalid number of args to $0" 363 fi 364 365 _replace_str="$1" 366 _replace_needle="$2" 367 _replace_replacement="$3" 368 369 substring_replace "$_replace_str" "%%$_replace_needle%%" "$_replace_replacement" 370} 371 372# This function finds all the source files that need to be built. If there is 373# only one argument and it is empty, then all source files are built. Otherwise, 374# the arguments are all assumed to be source files that should *not* be built. 375find_src_files() { 376 377 if [ "$#" -ge 1 ] && [ "$1" != "" ]; then 378 379 while [ "$#" -ge 1 ]; do 380 _find_src_files_a="${1## }" 381 shift 382 _find_src_files_args="$_find_src_files_args ! -path src/${_find_src_files_a}" 383 done 384 385 else 386 _find_src_files_args="-print" 387 fi 388 389 printf '%s\n' $(find src/ -depth -name "*.c" $_find_src_files_args) 390} 391 392# This function generates a list of files to go into the Makefile. It generates 393# the list of object files, as well as the list of test coverage files. 394# 395# @param contents The contents of the Makefile template to put the list of 396# files into. 397gen_file_list() { 398 399 if [ "$#" -lt 1 ]; then 400 err_exit "Invalid number of args to $0" 401 fi 402 403 _gen_file_list_contents="$1" 404 shift 405 406 p=$(pwd) 407 408 cd "$scriptdir" 409 410 if [ "$#" -ge 1 ]; then 411 _gen_file_list_unneeded="$@" 412 else 413 _gen_file_list_unneeded="" 414 fi 415 416 _gen_file_list_needle_src="SRC" 417 _gen_file_list_needle_obj="OBJ" 418 _gen_file_list_needle_gcda="GCDA" 419 _gen_file_list_needle_gcno="GCNO" 420 421 _gen_file_list_replacement=$(find_src_files $_gen_file_list_unneeded | tr '\n' ' ') 422 _gen_file_list_contents=$(replace "$_gen_file_list_contents" \ 423 "$_gen_file_list_needle_src" "$_gen_file_list_replacement") 424 425 _gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "c" "o") 426 _gen_file_list_contents=$(replace "$_gen_file_list_contents" \ 427 "$_gen_file_list_needle_obj" "$_gen_file_list_replacement") 428 429 _gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "o" "gcda") 430 _gen_file_list_contents=$(replace "$_gen_file_list_contents" \ 431 "$_gen_file_list_needle_gcda" "$_gen_file_list_replacement") 432 433 _gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "gcda" "gcno") 434 _gen_file_list_contents=$(replace "$_gen_file_list_contents" \ 435 "$_gen_file_list_needle_gcno" "$_gen_file_list_replacement") 436 437 cd "$p" 438 439 printf '%s\n' "$_gen_file_list_contents" 440} 441 442# Generates the proper test targets for each test to have its own target. This 443# allows `make test` to run in parallel. 444# 445# @param name Which calculator to generate tests for. 446# @param extra_math An integer that, if non-zero, activates extra math tests. 447# @param time_tests An integer that, if non-zero, tells the test suite to time 448# the execution of each test. 449gen_tests() { 450 451 _gen_tests_name="$1" 452 shift 453 454 _gen_tests_extra_math="$1" 455 shift 456 457 _gen_tests_time_tests="$1" 458 shift 459 460 _gen_tests_extra_required=$(cat "$scriptdir/tests/extra_required.txt") 461 462 for _gen_tests_t in $(cat "$scriptdir/tests/$_gen_tests_name/all.txt"); do 463 464 if [ "$_gen_tests_extra_math" -eq 0 ]; then 465 466 if [ -z "${_gen_tests_extra_required##*$_gen_tests_t*}" ]; then 467 printf 'test_%s_%s:\n\t@printf "Skipping %s %s\\n"\n\n' \ 468 "$_gen_tests_name" "$_gen_tests_t" "$_gen_tests_name" \ 469 "$_gen_tests_t" >> "$scriptdir/Makefile" 470 continue 471 fi 472 473 fi 474 475 printf 'test_%s_%s:\n\t@sh tests/test.sh %s %s %s %s %s\n\n' \ 476 "$_gen_tests_name" "$_gen_tests_t" "$_gen_tests_name" \ 477 "$_gen_tests_t" "$generate_tests" "$time_tests" \ 478 "$*" >> "$scriptdir/Makefile" 479 480 done 481} 482 483# Generates a list of test targets that will be used as prerequisites for other 484# targets. 485# 486# @param name The name of the calculator to generate test targets for. 487gen_test_targets() { 488 489 _gen_test_targets_name="$1" 490 shift 491 492 _gen_test_targets_tests=$(cat "$scriptdir/tests/${_gen_test_targets_name}/all.txt") 493 494 for _gen_test_targets_t in $_gen_test_targets_tests; do 495 printf ' test_%s_%s' "$_gen_test_targets_name" "$_gen_test_targets_t" 496 done 497 498 printf '\n' 499} 500 501# Generates the proper script test targets for each script test to have its own 502# target. This allows `make test` to run in parallel. 503# 504# @param name Which calculator to generate tests for. 505# @param extra_math An integer that, if non-zero, activates extra math tests. 506# @param generate An integer that, if non-zero, activates generated tests. 507# @param time_tests An integer that, if non-zero, tells the test suite to time 508# the execution of each test. 509gen_script_tests() { 510 511 _gen_script_tests_name="$1" 512 shift 513 514 _gen_script_tests_extra_math="$1" 515 shift 516 517 _gen_script_tests_generate="$1" 518 shift 519 520 _gen_script_tests_time="$1" 521 shift 522 523 _gen_script_tests_tests=$(cat "$scriptdir/tests/$_gen_script_tests_name/scripts/all.txt") 524 525 for _gen_script_tests_f in $_gen_script_tests_tests; do 526 527 _gen_script_tests_b=$(basename "$_gen_script_tests_f" ".${_gen_script_tests_name}") 528 529 printf 'test_%s_script_%s:\n\t@sh tests/script.sh %s %s %s 1 %s %s %s\n\n' \ 530 "$_gen_script_tests_name" "$_gen_script_tests_b" "$_gen_script_tests_name" \ 531 "$_gen_script_tests_f" "$_gen_script_tests_extra_math" "$_gen_script_tests_generate" \ 532 "$_gen_script_tests_time" "$*" >> "$scriptdir/Makefile" 533 done 534} 535 536set_default() { 537 538 _set_default_on="$1" 539 shift 540 541 _set_default_name="$1" 542 shift 543 544 # The reason that the variables that are being set do not have the same 545 # non-collision avoidance that the other variables do is that we *do* want 546 # the settings of these variables to leak out of the function. They adjust 547 # the settings outside of the function. 548 case "$_set_default_name" in 549 550 bc.banner) bc_default_banner="$_set_default_on" ;; 551 bc.sigint_reset) bc_default_sigint_reset="$_set_default_on" ;; 552 dc.sigint_reset) dc_default_sigint_reset="$_set_default_on" ;; 553 bc.tty_mode) bc_default_tty_mode="$_set_default_on" ;; 554 dc.tty_mode) dc_default_tty_mode="$_set_default_on" ;; 555 bc.prompt) bc_default_prompt="$_set_default_on" ;; 556 dc.prompt) dc_default_prompt="$_set_default_on" ;; 557 ?) usage "Invalid setting: $_set_default_name" ;; 558 559 esac 560} 561 562# Generates a list of script test targets that will be used as prerequisites for 563# other targets. 564# 565# @param name The name of the calculator to generate script test targets for. 566gen_script_test_targets() { 567 568 _gen_script_test_targets_name="$1" 569 shift 570 571 _gen_script_test_targets_tests=$(cat "$scriptdir/tests/$_gen_script_test_targets_name/scripts/all.txt") 572 573 for _gen_script_test_targets_f in $_gen_script_test_targets_tests; do 574 _gen_script_test_targets_b=$(basename "$_gen_script_test_targets_f" \ 575 ".$_gen_script_test_targets_name") 576 printf ' test_%s_script_%s' "$_gen_script_test_targets_name" \ 577 "$_gen_script_test_targets_b" 578 done 579 580 printf '\n' 581} 582 583# This is a list of defaults, but it is also the list of possible options for 584# users to change. 585# 586# The development options are: force (force options even if they fail), valgrind 587# (build in a way suitable for valgrind testing), memcheck (same as valgrind), 588# and fuzzing (build in a way suitable for fuzzing). 589bc_only=0 590dc_only=0 591coverage=0 592karatsuba_len=32 593debug=0 594hist=1 595extra_math=1 596optimization="" 597generate_tests=1 598install_manpages=1 599nls=1 600force=0 601strip_bin=1 602all_locales=0 603library=0 604fuzz=0 605time_tests=0 606vg=0 607memcheck=0 608clean=1 609 610# The empty strings are because they depend on TTY mode. If they are directly 611# set, though, they will be integers. We test for empty strings later. 612bc_default_banner=0 613bc_default_sigint_reset=1 614dc_default_sigint_reset=1 615bc_default_tty_mode=1 616dc_default_tty_mode=0 617bc_default_prompt="" 618dc_default_prompt="" 619 620# getopts is a POSIX utility, but it cannot handle long options. Thus, the 621# handling of long options is done by hand, and that's the reason that short and 622# long options cannot be mixed. 623while getopts "abBcdDEfgGhHk:lMmNO:S:s:tTvz-" opt; do 624 625 case "$opt" in 626 a) library=1 ;; 627 b) bc_only=1 ;; 628 B) dc_only=1 ;; 629 c) coverage=1 ;; 630 C) clean=0 ;; 631 d) dc_only=1 ;; 632 D) bc_only=1 ;; 633 E) extra_math=0 ;; 634 f) force=1 ;; 635 g) debug=1 ;; 636 G) generate_tests=0 ;; 637 h) usage ;; 638 H) hist=0 ;; 639 k) karatsuba_len="$OPTARG" ;; 640 l) all_locales=1 ;; 641 m) memcheck=1 ;; 642 M) install_manpages=0 ;; 643 N) nls=0 ;; 644 O) optimization="$OPTARG" ;; 645 S) set_default 0 "$OPTARG" ;; 646 s) set_default 1 "$OPTARG" ;; 647 t) time_tests=1 ;; 648 T) strip_bin=0 ;; 649 v) vg=1 ;; 650 z) fuzz=1 ;; 651 -) 652 arg="$1" 653 arg="${arg#--}" 654 LONG_OPTARG="${arg#*=}" 655 case $arg in 656 help) usage ;; 657 library) library=1 ;; 658 bc-only) bc_only=1 ;; 659 dc-only) dc_only=1 ;; 660 coverage) coverage=1 ;; 661 debug) debug=1 ;; 662 force) force=1 ;; 663 prefix=?*) PREFIX="$LONG_OPTARG" ;; 664 prefix) 665 if [ "$#" -lt 2 ]; then 666 usage "No argument given for '--$arg' option" 667 fi 668 PREFIX="$2" 669 shift ;; 670 bindir=?*) BINDIR="$LONG_OPTARG" ;; 671 bindir) 672 if [ "$#" -lt 2 ]; then 673 usage "No argument given for '--$arg' option" 674 fi 675 BINDIR="$2" 676 shift ;; 677 includedir=?*) INCLUDEDIR="$LONG_OPTARG" ;; 678 includedir) 679 if [ "$#" -lt 2 ]; then 680 usage "No argument given for '--$arg' option" 681 fi 682 INCLUDEDIR="$2" 683 shift ;; 684 libdir=?*) LIBDIR="$LONG_OPTARG" ;; 685 libdir) 686 if [ "$#" -lt 2 ]; then 687 usage "No argument given for '--$arg' option" 688 fi 689 LIBDIR="$2" 690 shift ;; 691 datarootdir=?*) DATAROOTDIR="$LONG_OPTARG" ;; 692 datarootdir) 693 if [ "$#" -lt 2 ]; then 694 usage "No argument given for '--$arg' option" 695 fi 696 DATAROOTDIR="$2" 697 shift ;; 698 datadir=?*) DATADIR="$LONG_OPTARG" ;; 699 datadir) 700 if [ "$#" -lt 2 ]; then 701 usage "No argument given for '--$arg' option" 702 fi 703 DATADIR="$2" 704 shift ;; 705 mandir=?*) MANDIR="$LONG_OPTARG" ;; 706 mandir) 707 if [ "$#" -lt 2 ]; then 708 usage "No argument given for '--$arg' option" 709 fi 710 MANDIR="$2" 711 shift ;; 712 man1dir=?*) MAN1DIR="$LONG_OPTARG" ;; 713 man1dir) 714 if [ "$#" -lt 2 ]; then 715 usage "No argument given for '--$arg' option" 716 fi 717 MAN1DIR="$2" 718 shift ;; 719 man3dir=?*) MAN3DIR="$LONG_OPTARG" ;; 720 man3dir) 721 if [ "$#" -lt 2 ]; then 722 usage "No argument given for '--$arg' option" 723 fi 724 MAN3DIR="$2" 725 shift ;; 726 localedir=?*) LOCALEDIR="$LONG_OPTARG" ;; 727 localedir) 728 if [ "$#" -lt 2 ]; then 729 usage "No argument given for '--$arg' option" 730 fi 731 LOCALEDIR="$2" 732 shift ;; 733 karatsuba-len=?*) karatsuba_len="$LONG_OPTARG" ;; 734 karatsuba-len) 735 if [ "$#" -lt 2 ]; then 736 usage "No argument given for '--$arg' option" 737 fi 738 karatsuba_len="$1" 739 shift ;; 740 opt=?*) optimization="$LONG_OPTARG" ;; 741 opt) 742 if [ "$#" -lt 2 ]; then 743 usage "No argument given for '--$arg' option" 744 fi 745 optimization="$1" 746 shift ;; 747 set-default-on=?*) set_default 1 "$LONG_OPTARG" ;; 748 set-default-on) 749 if [ "$#" -lt 2 ]; then 750 usage "No argument given for '--$arg' option" 751 fi 752 set_default 1 "$1" 753 shift ;; 754 set-default-off=?*) set_default 0 "$LONG_OPTARG" ;; 755 set-default-off) 756 if [ "$#" -lt 2 ]; then 757 usage "No argument given for '--$arg' option" 758 fi 759 set_default 0 "$1" 760 shift ;; 761 disable-bc) dc_only=1 ;; 762 disable-dc) bc_only=1 ;; 763 disable-clean) clean=0 ;; 764 disable-extra-math) extra_math=0 ;; 765 disable-generated-tests) generate_tests=0 ;; 766 disable-history) hist=0 ;; 767 disable-man-pages) install_manpages=0 ;; 768 disable-nls) nls=0 ;; 769 disable-strip) strip_bin=0 ;; 770 enable-test-timing) time_tests=1 ;; 771 enable-valgrind) vg=1 ;; 772 enable-fuzz-mode) fuzz=1 ;; 773 enable-memcheck) memcheck=1 ;; 774 install-all-locales) all_locales=1 ;; 775 help* | bc-only* | dc-only* | coverage* | debug*) 776 usage "No arg allowed for --$arg option" ;; 777 disable-bc* | disable-dc* | disable-clean*) 778 usage "No arg allowed for --$arg option" ;; 779 disable-extra-math*) 780 usage "No arg allowed for --$arg option" ;; 781 disable-generated-tests* | disable-history*) 782 usage "No arg allowed for --$arg option" ;; 783 disable-man-pages* | disable-nls* | disable-strip*) 784 usage "No arg allowed for --$arg option" ;; 785 enable-fuzz-mode* | enable-test-timing* | enable-valgrind*) 786 usage "No arg allowed for --$arg option" ;; 787 enable-memcheck* | install-all-locales*) 788 usage "No arg allowed for --$arg option" ;; 789 '') break ;; # "--" terminates argument processing 790 * ) usage "Invalid option $LONG_OPTARG" ;; 791 esac 792 shift 793 OPTIND=1 ;; 794 ?) usage "Invalid option: $opt" ;; 795 esac 796 797done 798 799# Sometimes, developers don't want configure.sh to do a config clean. But 800# sometimes they do. 801if [ "$clean" -ne 0 ]; then 802 if [ -f ./Makefile ]; then 803 make clean_config > /dev/null 804 fi 805fi 806 807# It is an error to say that bc only should be built and likewise for dc. 808if [ "$bc_only" -eq 1 ] && [ "$dc_only" -eq 1 ]; then 809 usage "Can only specify one of -b(-D) or -d(-B)" 810fi 811 812# The library is mutually exclusive to the calculators, so it's an error to 813# give an option for either of them. 814if [ "$library" -ne 0 ]; then 815 if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then 816 usage "Must not specify -b(-D) or -d(-B) when building the library" 817 fi 818fi 819 820# KARATSUBA_LEN must be an integer and must be 16 or greater. 821case $karatsuba_len in 822 (*[!0-9]*|'') usage "KARATSUBA_LEN is not a number" ;; 823 (*) ;; 824esac 825 826if [ "$karatsuba_len" -lt 16 ]; then 827 usage "KARATSUBA_LEN is less than 16" 828fi 829 830set -e 831 832if [ -z "${LONG_BIT+set}" ]; then 833 LONG_BIT_DEFINE="" 834elif [ "$LONG_BIT" -lt 32 ]; then 835 usage "LONG_BIT is less than 32" 836else 837 LONG_BIT_DEFINE="-DBC_LONG_BIT=\$(BC_LONG_BIT)" 838fi 839 840if [ -z "$CC" ]; then 841 CC="c99" 842else 843 844 # I had users complain that, if they gave CFLAGS as part of CC, which 845 # autotools allows in its braindead way, the build would fail with an error. 846 # I don't like adjusting for autotools, but oh well. These lines puts the 847 # stuff after the first space into CFLAGS. 848 ccbase=$(basename "$CC") 849 suffix=" *" 850 prefix="* " 851 852 if [ "${ccbase%%$suffix}" != "$ccbase" ]; then 853 ccflags="${ccbase#$prefix}" 854 cc="${ccbase%%$suffix}" 855 ccdir=$(dirname "$CC") 856 if [ "$ccdir" = "." ] && [ "${CC#.}" = "$CC" ]; then 857 ccdir="" 858 else 859 ccdir="$ccdir/" 860 fi 861 CC="${ccdir}${cc}" 862 CFLAGS="$CFLAGS $ccflags" 863 fi 864fi 865 866if [ -z "$HOSTCC" ] && [ -z "$HOST_CC" ]; then 867 HOSTCC="$CC" 868elif [ -z "$HOSTCC" ]; then 869 HOSTCC="$HOST_CC" 870fi 871 872if [ "$HOSTCC" != "$CC" ]; then 873 874 # Like above, this splits HOSTCC and HOSTCFLAGS. 875 ccbase=$(basename "$HOSTCC") 876 suffix=" *" 877 prefix="* " 878 879 if [ "${ccbase%%$suffix}" != "$ccbase" ]; then 880 ccflags="${ccbase#$prefix}" 881 cc="${ccbase%%$suffix}" 882 ccdir=$(dirname "$HOSTCC") 883 if [ "$ccdir" = "." ] && [ "${HOSTCC#.}" = "$HOSTCC" ]; then 884 ccdir="" 885 else 886 ccdir="$ccdir/" 887 fi 888 HOSTCC="${ccdir}${cc}" 889 HOSTCFLAGS="$HOSTCFLAGS $ccflags" 890 fi 891fi 892 893if [ -z "${HOSTCFLAGS+set}" ] && [ -z "${HOST_CFLAGS+set}" ]; then 894 HOSTCFLAGS="$CFLAGS" 895elif [ -z "${HOSTCFLAGS+set}" ]; then 896 HOSTCFLAGS="$HOST_CFLAGS" 897fi 898 899# Store these for the cross compilation detection later. 900OLDCFLAGS="$CFLAGS" 901OLDHOSTCFLAGS="$HOSTCFLAGS" 902 903link="@printf 'No link necessary\\\\n'" 904main_exec="BC" 905executable="BC_EXEC" 906 907tests="test_bc timeconst test_dc test_history" 908 909bc_test="@tests/all.sh bc $extra_math 1 $generate_tests $time_tests \$(BC_EXEC)" 910dc_test="@tests/all.sh dc $extra_math 1 $generate_tests $time_tests \$(DC_EXEC)" 911 912timeconst="@tests/bc/timeconst.sh tests/bc/scripts/timeconst.bc \$(BC_EXEC)" 913 914# In order to have cleanup at exit, we need to be in 915# debug mode, so don't run valgrind without that. 916if [ "$vg" -ne 0 ]; then 917 debug=1 918 bc_test_exec='valgrind $(VALGRIND_ARGS) $(BC_EXEC)' 919 dc_test_exec='valgrind $(VALGRIND_ARGS) $(DC_EXEC)' 920else 921 bc_test_exec='$(BC_EXEC)' 922 dc_test_exec='$(DC_EXEC)' 923fi 924 925test_bc_history_prereqs="test_bc_history_all" 926test_dc_history_prereqs="test_dc_history_all" 927 928karatsuba="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'" 929karatsuba_test="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'" 930 931bc_lib="\$(GEN_DIR)/lib.o" 932bc_help="\$(GEN_DIR)/bc_help.o" 933dc_help="\$(GEN_DIR)/dc_help.o" 934 935default_target_prereqs="\$(BIN) \$(OBJS)" 936default_target_cmd="\$(CC) \$(CFLAGS) \$(OBJS) \$(LDFLAGS) -o \$(EXEC)" 937default_target="\$(DC_EXEC)" 938 939second_target_prereqs="" 940second_target_cmd="$default_target_cmd" 941second_target="\$(BC_EXEC)" 942 943# This if/else if chain is for setting the defaults that change based on whether 944# the library is being built, bc only, dc only, or both calculators. 945if [ "$library" -ne 0 ]; then 946 947 extra_math=1 948 nls=0 949 hist=0 950 bc=1 951 dc=1 952 953 default_target_prereqs="\$(BIN) \$(OBJ)" 954 default_target_cmd="ar -r -cu \$(LIBBC) \$(OBJ)" 955 default_target="\$(LIBBC)" 956 tests="test_library" 957 test_bc_history_prereqs=" test_bc_history_skip" 958 test_dc_history_prereqs=" test_dc_history_skip" 959 960elif [ "$bc_only" -eq 1 ]; then 961 962 bc=1 963 dc=0 964 965 dc_help="" 966 967 executables="bc" 968 969 dc_test="@printf 'No dc tests to run\\\\n'" 970 test_dc_history_prereqs=" test_dc_history_skip" 971 972 install_prereqs=" install_execs" 973 install_man_prereqs=" install_bc_manpage" 974 uninstall_prereqs=" uninstall_bc" 975 uninstall_man_prereqs=" uninstall_bc_manpage" 976 977 default_target="\$(BC_EXEC)" 978 second_target="\$(DC_EXEC)" 979 tests="test_bc timeconst test_history" 980 981elif [ "$dc_only" -eq 1 ]; then 982 983 bc=0 984 dc=1 985 986 bc_lib="" 987 bc_help="" 988 989 executables="dc" 990 991 main_exec="DC" 992 executable="DC_EXEC" 993 994 bc_test="@printf 'No bc tests to run\\\\n'" 995 test_bc_history_prereqs=" test_bc_history_skip" 996 997 timeconst="@printf 'timeconst cannot be run because bc is not built\\\\n'" 998 999 install_prereqs=" install_execs" 1000 install_man_prereqs=" install_dc_manpage" 1001 uninstall_prereqs=" uninstall_dc" 1002 uninstall_man_prereqs=" uninstall_dc_manpage" 1003 1004 tests="test_dc test_history" 1005 1006else 1007 1008 bc=1 1009 dc=1 1010 1011 executables="bc and dc" 1012 1013 karatsuba="@\$(KARATSUBA) 30 0 \$(BC_EXEC)" 1014 karatsuba_test="@\$(KARATSUBA) 1 100 \$(BC_EXEC)" 1015 1016 if [ "$library" -eq 0 ]; then 1017 install_prereqs=" install_execs" 1018 install_man_prereqs=" install_bc_manpage install_dc_manpage" 1019 uninstall_prereqs=" uninstall_bc uninstall_dc" 1020 uninstall_man_prereqs=" uninstall_bc_manpage uninstall_dc_manpage" 1021 else 1022 install_prereqs=" install_library install_bcl_header" 1023 install_man_prereqs=" install_bcl_manpage" 1024 uninstall_prereqs=" uninstall_library uninstall_bcl_header" 1025 uninstall_man_prereqs=" uninstall_bcl_manpage" 1026 tests="test_library" 1027 fi 1028 1029 second_target_prereqs="$default_target_prereqs" 1030 default_target_prereqs="$second_target" 1031 default_target_cmd="\$(LINK) \$(BIN) \$(EXEC_PREFIX)\$(DC)" 1032 1033fi 1034 1035# We need specific stuff for fuzzing. 1036if [ "$fuzz" -ne 0 ]; then 1037 debug=1 1038 hist=0 1039 nls=0 1040 optimization="3" 1041fi 1042 1043# This sets some necessary things for debug mode. 1044if [ "$debug" -eq 1 ]; then 1045 1046 if [ -z "$CFLAGS" ] && [ -z "$optimization" ]; then 1047 CFLAGS="-O0" 1048 fi 1049 1050 CFLAGS="-g $CFLAGS" 1051 1052else 1053 1054 CPPFLAGS="-DNDEBUG $CPPFLAGS" 1055 1056 if [ "$strip_bin" -ne 0 ]; then 1057 LDFLAGS="-s $LDFLAGS" 1058 fi 1059fi 1060 1061# Set optimization CFLAGS. 1062if [ -n "$optimization" ]; then 1063 CFLAGS="-O$optimization $CFLAGS" 1064fi 1065 1066# Set test coverage defaults. 1067if [ "$coverage" -eq 1 ]; then 1068 1069 if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then 1070 usage "Can only specify -c without -b or -d" 1071 fi 1072 1073 CFLAGS="-fprofile-arcs -ftest-coverage -g -O0 $CFLAGS" 1074 CPPFLAGS="-DNDEBUG $CPPFLAGS" 1075 1076 COVERAGE_OUTPUT="@gcov -pabcdf \$(GCDA) \$(BC_GCDA) \$(DC_GCDA) \$(HISTORY_GCDA) \$(RAND_GCDA)" 1077 COVERAGE_OUTPUT="$COVERAGE_OUTPUT;\$(RM) -f \$(GEN)*.gc*" 1078 COVERAGE_OUTPUT="$COVERAGE_OUTPUT;gcovr --exclude-unreachable-branches --exclude-throw-branches --html-details --output index.html" 1079 COVERAGE_PREREQS=" test coverage_output" 1080 1081else 1082 COVERAGE_OUTPUT="@printf 'Coverage not generated\\\\n'" 1083 COVERAGE_PREREQS="" 1084fi 1085 1086 1087# Set some defaults. 1088if [ -z "${DESTDIR+set}" ]; then 1089 destdir="" 1090else 1091 destdir="DESTDIR = $DESTDIR" 1092fi 1093 1094if [ -z "${PREFIX+set}" ]; then 1095 PREFIX="/usr/local" 1096fi 1097 1098if [ -z "${BINDIR+set}" ]; then 1099 BINDIR="$PREFIX/bin" 1100fi 1101 1102if [ -z "${INCLUDEDIR+set}" ]; then 1103 INCLUDEDIR="$PREFIX/include" 1104fi 1105 1106if [ -z "${LIBDIR+set}" ]; then 1107 LIBDIR="$PREFIX/lib" 1108fi 1109 1110# Set a default for the DATAROOTDIR. This is done if either manpages will be 1111# installed, or locales are enabled because that's probably where NLS_PATH 1112# points. 1113if [ "$install_manpages" -ne 0 ] || [ "$nls" -ne 0 ]; then 1114 if [ -z "${DATAROOTDIR+set}" ]; then 1115 DATAROOTDIR="$PREFIX/share" 1116 fi 1117fi 1118 1119# Set defaults for manpage environment variables. 1120if [ "$install_manpages" -ne 0 ]; then 1121 1122 if [ -z "${DATADIR+set}" ]; then 1123 DATADIR="$DATAROOTDIR" 1124 fi 1125 1126 if [ -z "${MANDIR+set}" ]; then 1127 MANDIR="$DATADIR/man" 1128 fi 1129 1130 if [ -z "${MAN1DIR+set}" ]; then 1131 MAN1DIR="$MANDIR/man1" 1132 fi 1133 1134 if [ -z "${MAN3DIR+set}" ]; then 1135 MAN3DIR="$MANDIR/man3" 1136 fi 1137 1138else 1139 install_man_prereqs="" 1140 uninstall_man_prereqs="" 1141fi 1142 1143# Here is where we test NLS (the locale system). This is done by trying to 1144# compile src/vm.c, which has the relevant code. If it fails, then it is 1145# disabled. 1146if [ "$nls" -ne 0 ]; then 1147 1148 set +e 1149 1150 printf 'Testing NLS...\n' 1151 1152 flags="-DBC_ENABLE_NLS=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc" 1153 flags="$flags -DBC_ENABLE_HISTORY=$hist -DBC_ENABLE_LIBRARY=0 -DBC_ENABLE_AFL=0" 1154 flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/" 1155 flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700" 1156 1157 "$CC" $CPPFLAGS $CFLAGS $flags -c "src/vm.c" -o "$scriptdir/vm.o" > /dev/null 2>&1 1158 1159 err="$?" 1160 1161 rm -rf "$scriptdir/vm.o" 1162 1163 # If this errors, it is probably because of building on Windows, 1164 # and NLS is not supported on Windows, so disable it. 1165 if [ "$err" -ne 0 ]; then 1166 printf 'NLS does not work.\n' 1167 if [ $force -eq 0 ]; then 1168 printf 'Disabling NLS...\n\n' 1169 nls=0 1170 else 1171 printf 'Forcing NLS...\n\n' 1172 fi 1173 else 1174 printf 'NLS works.\n\n' 1175 1176 printf 'Testing gencat...\n' 1177 gencat "$scriptdir/en_US.cat" "$scriptdir/locales/en_US.msg" > /dev/null 2>&1 1178 1179 err="$?" 1180 1181 rm -rf "$scriptdir/en_US.cat" 1182 1183 if [ "$err" -ne 0 ]; then 1184 printf 'gencat does not work.\n' 1185 if [ $force -eq 0 ]; then 1186 printf 'Disabling NLS...\n\n' 1187 nls=0 1188 else 1189 printf 'Forcing NLS...\n\n' 1190 fi 1191 else 1192 1193 printf 'gencat works.\n\n' 1194 1195 # It turns out that POSIX locales are really terrible, and running 1196 # gencat on one machine is not guaranteed to make those cat files 1197 # portable to another machine, so we had better warn the user here. 1198 if [ "$HOSTCC" != "$CC" ] || [ "$OLDHOSTCFLAGS" != "$OLDCFLAGS" ]; then 1199 printf 'Cross-compile detected.\n\n' 1200 printf 'WARNING: Catalog files generated with gencat may not be portable\n' 1201 printf ' across different architectures.\n\n' 1202 fi 1203 1204 if [ -z "$NLSPATH" ]; then 1205 NLSPATH="/usr/share/locale/%L/%N" 1206 fi 1207 1208 install_locales_prereqs=" install_locales" 1209 uninstall_locales_prereqs=" uninstall_locales" 1210 1211 fi 1212 1213 fi 1214 1215 set -e 1216 1217else 1218 install_locales_prereqs="" 1219 uninstall_locales_prereqs="" 1220 all_locales=0 1221fi 1222 1223if [ "$nls" -ne 0 ] && [ "$all_locales" -ne 0 ]; then 1224 install_locales="\$(LOCALE_INSTALL) -l \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)" 1225else 1226 install_locales="\$(LOCALE_INSTALL) \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)" 1227fi 1228 1229# Like the above tested locale support, this tests history. 1230if [ "$hist" -eq 1 ]; then 1231 1232 set +e 1233 1234 printf 'Testing history...\n' 1235 1236 flags="-DBC_ENABLE_HISTORY=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc" 1237 flags="$flags -DBC_ENABLE_NLS=$nls -DBC_ENABLE_LIBRARY=0 -DBC_ENABLE_AFL=0" 1238 flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/" 1239 flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700" 1240 1241 "$CC" $CPPFLAGS $CFLAGS $flags -c "src/history.c" -o "$scriptdir/history.o" > /dev/null 2>&1 1242 1243 err="$?" 1244 1245 rm -rf "$scriptdir/history.o" 1246 1247 # If this errors, it is probably because of building on Windows, 1248 # and history is not supported on Windows, so disable it. 1249 if [ "$err" -ne 0 ]; then 1250 printf 'History does not work.\n' 1251 if [ $force -eq 0 ]; then 1252 printf 'Disabling history...\n\n' 1253 hist=0 1254 else 1255 printf 'Forcing history...\n\n' 1256 fi 1257 else 1258 printf 'History works.\n\n' 1259 fi 1260 1261 set -e 1262 1263fi 1264 1265# We have to disable the history tests if it is disabled or valgrind is on. 1266if [ "$hist" -eq 0 ] || [ "$vg" -ne 0 ]; then 1267 test_bc_history_prereqs=" test_bc_history_skip" 1268 test_dc_history_prereqs=" test_dc_history_skip" 1269 history_tests="@printf 'Skipping history tests...\\\\n'" 1270else 1271 history_tests="@printf '\$(TEST_STARS)\\\\n\\\\nRunning history tests...\\\\n\\\\n' \&\& tests/history.sh bc -a \&\& tests/history.sh dc -a \&\& printf '\\\\nAll history tests passed.\\\\n\\\\n\$(TEST_STARS)\\\\n'" 1272fi 1273 1274# Test OpenBSD. This is not in an if statement because regardless of whatever 1275# the user says, we need to know if we are on OpenBSD to activate _BSD_SOURCE. 1276# No, I cannot `#define _BSD_SOURCE` in a header because OpenBSD's patched GCC 1277# and Clang complain that that is only allowed for system headers. Sigh....So we 1278# have to check at configure time and set it on the compiler command-line. And 1279# we have to set it because we also set _POSIX_C_SOURCE, which OpenBSD headers 1280# detect, and when they detect it, they turn off _BSD_SOURCE unless it is 1281# specifically requested. 1282set +e 1283printf 'Testing for OpenBSD...\n' 1284 1285flags="-DBC_TEST_OPENBSD -DBC_ENABLE_AFL=0" 1286"$CC" $CPPFLAGS $CFLAGS $flags -I./include -E "include/status.h" > /dev/null 2>&1 1287 1288err="$?" 1289 1290if [ "$err" -ne 0 ]; then 1291 printf 'On OpenBSD. Using _BSD_SOURCE.\n\n' 1292 bsd="-D_BSD_SOURCE" 1293else 1294 printf 'Not on OpenBSD.\n\n' 1295 bsd="" 1296fi 1297 1298if [ "$library" -eq 1 ]; then 1299 bc_lib="" 1300fi 1301 1302if [ "$extra_math" -eq 1 ] && [ "$bc" -ne 0 ] && [ "$library" -eq 0 ]; then 1303 BC_LIB2_O="\$(GEN_DIR)/lib2.o" 1304else 1305 BC_LIB2_O="" 1306fi 1307 1308# These lines set the appropriate targets based on whether `gen/strgen.c` or 1309# `gen/strgen.sh` is used. 1310GEN="strgen" 1311GEN_EXEC_TARGET="\$(HOSTCC) \$(HOSTCFLAGS) -o \$(GEN_EXEC) \$(GEN_C)" 1312CLEAN_PREREQS=" clean_gen clean_coverage" 1313 1314if [ -z "${GEN_HOST+set}" ]; then 1315 GEN_HOST=1 1316else 1317 if [ "$GEN_HOST" -eq 0 ]; then 1318 GEN="strgen.sh" 1319 GEN_EXEC_TARGET="@printf 'Do not need to build gen/strgen.c\\\\n'" 1320 CLEAN_PREREQS=" clean_coverage" 1321 fi 1322fi 1323 1324manpage_args="" 1325unneeded="" 1326headers="\$(HEADERS)" 1327 1328# This series of if statements figure out what source files are *not* needed. 1329if [ "$extra_math" -eq 0 ]; then 1330 manpage_args="E" 1331 unneeded="$unneeded rand.c" 1332else 1333 headers="$headers \$(EXTRA_MATH_HEADERS)" 1334fi 1335 1336# All of these next if statements set the build type and mark certain source 1337# files as unneeded so that they won't have targets generated for them. 1338 1339if [ "$hist" -eq 0 ]; then 1340 manpage_args="${manpage_args}H" 1341 unneeded="$unneeded history.c" 1342else 1343 headers="$headers \$(HISTORY_HEADERS)" 1344fi 1345 1346if [ "$nls" -eq 0 ]; then 1347 manpage_args="${manpage_args}N" 1348fi 1349 1350if [ "$bc" -eq 0 ]; then 1351 unneeded="$unneeded bc.c bc_lex.c bc_parse.c" 1352else 1353 headers="$headers \$(BC_HEADERS)" 1354fi 1355 1356if [ "$dc" -eq 0 ]; then 1357 unneeded="$unneeded dc.c dc_lex.c dc_parse.c" 1358else 1359 headers="$headers \$(DC_HEADERS)" 1360fi 1361 1362if [ "$library" -ne 0 ]; then 1363 unneeded="$unneeded args.c opt.c read.c file.c main.c" 1364 unneeded="$unneeded lang.c lex.c parse.c program.c" 1365 unneeded="$unneeded bc.c bc_lex.c bc_parse.c" 1366 unneeded="$unneeded dc.c dc_lex.c dc_parse.c" 1367 headers="$headers \$(LIBRARY_HEADERS)" 1368else 1369 unneeded="$unneeded library.c" 1370fi 1371 1372# library.c is not needed under normal circumstances. 1373if [ "$unneeded" = "" ]; then 1374 unneeded="library.c" 1375fi 1376 1377# This sets the appropriate manpage for a full build. 1378if [ "$manpage_args" = "" ]; then 1379 manpage_args="A" 1380fi 1381 1382if [ "$vg" -ne 0 ]; then 1383 memcheck=1 1384fi 1385 1386if [ "$bc_default_prompt" = "" ]; then 1387 bc_default_prompt="$bc_default_tty_mode" 1388fi 1389 1390if [ "$dc_default_prompt" = "" ]; then 1391 dc_default_prompt="$dc_default_tty_mode" 1392fi 1393 1394# Generate the test targets and prerequisites. 1395bc_tests=$(gen_test_targets bc) 1396bc_script_tests=$(gen_script_test_targets bc) 1397dc_tests=$(gen_test_targets dc) 1398dc_script_tests=$(gen_script_test_targets dc) 1399 1400# Print out the values; this is for debugging. 1401if [ "$bc" -ne 0 ]; then 1402 printf 'Building bc\n' 1403else 1404 printf 'Not building bc\n' 1405fi 1406if [ "$dc" -ne 0 ]; then 1407 printf 'Building dc\n' 1408else 1409 printf 'Not building dc\n' 1410fi 1411printf '\n' 1412printf 'BC_ENABLE_LIBRARY=%s\n\n' "$library" 1413printf 'BC_ENABLE_HISTORY=%s\n' "$hist" 1414printf 'BC_ENABLE_EXTRA_MATH=%s\n' "$extra_math" 1415printf 'BC_ENABLE_NLS=%s\n' "$nls" 1416printf 'BC_ENABLE_AFL=%s\n' "$fuzz" 1417printf '\n' 1418printf 'BC_NUM_KARATSUBA_LEN=%s\n' "$karatsuba_len" 1419printf '\n' 1420printf 'CC=%s\n' "$CC" 1421printf 'CFLAGS=%s\n' "$CFLAGS" 1422printf 'HOSTCC=%s\n' "$HOSTCC" 1423printf 'HOSTCFLAGS=%s\n' "$HOSTCFLAGS" 1424printf 'CPPFLAGS=%s\n' "$CPPFLAGS" 1425printf 'LDFLAGS=%s\n' "$LDFLAGS" 1426printf 'PREFIX=%s\n' "$PREFIX" 1427printf 'BINDIR=%s\n' "$BINDIR" 1428printf 'INCLUDEDIR=%s\n' "$INCLUDEDIR" 1429printf 'LIBDIR=%s\n' "$LIBDIR" 1430printf 'DATAROOTDIR=%s\n' "$DATAROOTDIR" 1431printf 'DATADIR=%s\n' "$DATADIR" 1432printf 'MANDIR=%s\n' "$MANDIR" 1433printf 'MAN1DIR=%s\n' "$MAN1DIR" 1434printf 'MAN3DIR=%s\n' "$MAN3DIR" 1435printf 'NLSPATH=%s\n' "$NLSPATH" 1436printf 'EXECSUFFIX=%s\n' "$EXECSUFFIX" 1437printf 'EXECPREFIX=%s\n' "$EXECPREFIX" 1438printf 'DESTDIR=%s\n' "$DESTDIR" 1439printf 'LONG_BIT=%s\n' "$LONG_BIT" 1440printf 'GEN_HOST=%s\n' "$GEN_HOST" 1441printf 'GEN_EMU=%s\n' "$GEN_EMU" 1442printf '\n' 1443printf 'Setting Defaults\n' 1444printf '================\n' 1445printf 'bc.banner=%s\n' "$bc_default_banner" 1446printf 'bc.sigint_reset=%s\n' "$bc_default_sigint_reset" 1447printf 'dc.sigint_reset=%s\n' "$dc_default_sigint_reset" 1448printf 'bc.tty_mode=%s\n' "$bc_default_tty_mode" 1449printf 'dc.tty_mode=%s\n' "$dc_default_tty_mode" 1450printf 'bc.prompt=%s\n' "$bc_default_prompt" 1451printf 'dc.prompt=%s\n' "$dc_default_prompt" 1452 1453# This is where the real work begins. This is the point at which the Makefile.in 1454# template is edited and output to the Makefile. 1455 1456contents=$(cat "$scriptdir/Makefile.in") 1457 1458needle="WARNING" 1459replacement='*** WARNING: Autogenerated from Makefile.in. DO NOT MODIFY ***' 1460 1461contents=$(replace "$contents" "$needle" "$replacement") 1462 1463# The contents are edited to have the list of files to build. 1464contents=$(gen_file_list "$contents" $unneeded) 1465 1466SRC_TARGETS="" 1467 1468# This line and loop generates the individual targets for source files. I used 1469# to just use an implicit target, but that was found to be inadequate when I 1470# added the library. 1471src_files=$(find_src_files $unneeded) 1472 1473for f in $src_files; do 1474 o=$(replace_ext "$f" "c" "o") 1475 SRC_TARGETS=$(printf '%s\n\n%s: %s %s\n\t$(CC) $(CFLAGS) -o %s -c %s\n' \ 1476 "$SRC_TARGETS" "$o" "$headers" "$f" "$o" "$f") 1477done 1478 1479# Replace all the placeholders. 1480contents=$(replace "$contents" "HEADERS" "$headers") 1481 1482contents=$(replace "$contents" "BC_ENABLED" "$bc") 1483contents=$(replace "$contents" "DC_ENABLED" "$dc") 1484 1485contents=$(replace "$contents" "BC_ALL_TESTS" "$bc_test") 1486contents=$(replace "$contents" "BC_TESTS" "$bc_tests") 1487contents=$(replace "$contents" "BC_SCRIPT_TESTS" "$bc_script_tests") 1488contents=$(replace "$contents" "BC_TEST_EXEC" "$bc_test_exec") 1489contents=$(replace "$contents" "TIMECONST_ALL_TESTS" "$timeconst") 1490 1491contents=$(replace "$contents" "DC_ALL_TESTS" "$dc_test") 1492contents=$(replace "$contents" "DC_TESTS" "$dc_tests") 1493contents=$(replace "$contents" "DC_SCRIPT_TESTS" "$dc_script_tests") 1494contents=$(replace "$contents" "DC_TEST_EXEC" "$dc_test_exec") 1495 1496contents=$(replace "$contents" "BUILD_TYPE" "$manpage_args") 1497 1498contents=$(replace "$contents" "LIBRARY" "$library") 1499contents=$(replace "$contents" "HISTORY" "$hist") 1500contents=$(replace "$contents" "EXTRA_MATH" "$extra_math") 1501contents=$(replace "$contents" "NLS" "$nls") 1502contents=$(replace "$contents" "FUZZ" "$fuzz") 1503contents=$(replace "$contents" "MEMCHECK" "$memcheck") 1504 1505contents=$(replace "$contents" "BC_LIB_O" "$bc_lib") 1506contents=$(replace "$contents" "BC_HELP_O" "$bc_help") 1507contents=$(replace "$contents" "DC_HELP_O" "$dc_help") 1508contents=$(replace "$contents" "BC_LIB2_O" "$BC_LIB2_O") 1509contents=$(replace "$contents" "KARATSUBA_LEN" "$karatsuba_len") 1510 1511contents=$(replace "$contents" "NLSPATH" "$NLSPATH") 1512contents=$(replace "$contents" "DESTDIR" "$destdir") 1513contents=$(replace "$contents" "EXECSUFFIX" "$EXECSUFFIX") 1514contents=$(replace "$contents" "EXECPREFIX" "$EXECPREFIX") 1515contents=$(replace "$contents" "BINDIR" "$BINDIR") 1516contents=$(replace "$contents" "INCLUDEDIR" "$INCLUDEDIR") 1517contents=$(replace "$contents" "LIBDIR" "$LIBDIR") 1518contents=$(replace "$contents" "MAN1DIR" "$MAN1DIR") 1519contents=$(replace "$contents" "MAN3DIR" "$MAN3DIR") 1520contents=$(replace "$contents" "CFLAGS" "$CFLAGS") 1521contents=$(replace "$contents" "HOSTCFLAGS" "$HOSTCFLAGS") 1522contents=$(replace "$contents" "CPPFLAGS" "$CPPFLAGS") 1523contents=$(replace "$contents" "LDFLAGS" "$LDFLAGS") 1524contents=$(replace "$contents" "CC" "$CC") 1525contents=$(replace "$contents" "HOSTCC" "$HOSTCC") 1526contents=$(replace "$contents" "COVERAGE_OUTPUT" "$COVERAGE_OUTPUT") 1527contents=$(replace "$contents" "COVERAGE_PREREQS" "$COVERAGE_PREREQS") 1528contents=$(replace "$contents" "INSTALL_PREREQS" "$install_prereqs") 1529contents=$(replace "$contents" "INSTALL_MAN_PREREQS" "$install_man_prereqs") 1530contents=$(replace "$contents" "INSTALL_LOCALES" "$install_locales") 1531contents=$(replace "$contents" "INSTALL_LOCALES_PREREQS" "$install_locales_prereqs") 1532contents=$(replace "$contents" "UNINSTALL_MAN_PREREQS" "$uninstall_man_prereqs") 1533contents=$(replace "$contents" "UNINSTALL_PREREQS" "$uninstall_prereqs") 1534contents=$(replace "$contents" "UNINSTALL_LOCALES_PREREQS" "$uninstall_locales_prereqs") 1535 1536contents=$(replace "$contents" "DEFAULT_TARGET" "$default_target") 1537contents=$(replace "$contents" "DEFAULT_TARGET_PREREQS" "$default_target_prereqs") 1538contents=$(replace "$contents" "DEFAULT_TARGET_CMD" "$default_target_cmd") 1539contents=$(replace "$contents" "SECOND_TARGET" "$second_target") 1540contents=$(replace "$contents" "SECOND_TARGET_PREREQS" "$second_target_prereqs") 1541contents=$(replace "$contents" "SECOND_TARGET_CMD" "$second_target_cmd") 1542 1543contents=$(replace "$contents" "ALL_PREREQ" "$ALL_PREREQ") 1544contents=$(replace "$contents" "BC_EXEC_PREREQ" "$bc_exec_prereq") 1545contents=$(replace "$contents" "BC_EXEC_CMD" "$bc_exec_cmd") 1546contents=$(replace "$contents" "DC_EXEC_PREREQ" "$dc_exec_prereq") 1547contents=$(replace "$contents" "DC_EXEC_CMD" "$dc_exec_cmd") 1548 1549contents=$(replace "$contents" "EXECUTABLES" "$executables") 1550contents=$(replace "$contents" "MAIN_EXEC" "$main_exec") 1551contents=$(replace "$contents" "EXEC" "$executable") 1552contents=$(replace "$contents" "TESTS" "$tests") 1553 1554contents=$(replace "$contents" "BC_TEST" "$bc_test") 1555contents=$(replace "$contents" "BC_HISTORY_TEST_PREREQS" "$test_bc_history_prereqs") 1556contents=$(replace "$contents" "DC_TEST" "$dc_test") 1557contents=$(replace "$contents" "DC_HISTORY_TEST_PREREQS" "$test_dc_history_prereqs") 1558contents=$(replace "$contents" "HISTORY_TESTS" "$history_tests") 1559 1560contents=$(replace "$contents" "VG_BC_TEST" "$vg_bc_test") 1561contents=$(replace "$contents" "VG_DC_TEST" "$vg_dc_test") 1562 1563contents=$(replace "$contents" "TIMECONST" "$timeconst") 1564 1565contents=$(replace "$contents" "KARATSUBA" "$karatsuba") 1566contents=$(replace "$contents" "KARATSUBA_TEST" "$karatsuba_test") 1567 1568contents=$(replace "$contents" "LONG_BIT" "$LONG_BIT") 1569contents=$(replace "$contents" "LONG_BIT_DEFINE" "$LONG_BIT_DEFINE") 1570 1571contents=$(replace "$contents" "GEN" "$GEN") 1572contents=$(replace "$contents" "GEN_EXEC_TARGET" "$GEN_EXEC_TARGET") 1573contents=$(replace "$contents" "CLEAN_PREREQS" "$CLEAN_PREREQS") 1574contents=$(replace "$contents" "GEN_EMU" "$GEN_EMU") 1575 1576contents=$(replace "$contents" "BSD" "$bsd") 1577 1578contents=$(replace "$contents" "BC_DEFAULT_BANNER" "$bc_default_banner") 1579contents=$(replace "$contents" "BC_DEFAULT_SIGINT_RESET" "$bc_default_sigint_reset") 1580contents=$(replace "$contents" "DC_DEFAULT_SIGINT_RESET" "$dc_default_sigint_reset") 1581contents=$(replace "$contents" "BC_DEFAULT_TTY_MODE" "$bc_default_tty_mode") 1582contents=$(replace "$contents" "DC_DEFAULT_TTY_MODE" "$dc_default_tty_mode") 1583contents=$(replace "$contents" "BC_DEFAULT_PROMPT" "$bc_default_prompt") 1584contents=$(replace "$contents" "DC_DEFAULT_PROMPT" "$dc_default_prompt") 1585 1586# Do the first print to the Makefile. 1587printf '%s\n%s\n\n' "$contents" "$SRC_TARGETS" > "$scriptdir/Makefile" 1588 1589# Generate the individual test targets. 1590if [ "$bc" -ne 0 ]; then 1591 gen_tests bc "$extra_math" "$time_tests" $bc_test_exec 1592 gen_script_tests bc "$extra_math" "$generate_tests" "$time_tests" $bc_test_exec 1593fi 1594 1595if [ "$dc" -ne 0 ]; then 1596 gen_tests dc "$extra_math" "$time_tests" $dc_test_exec 1597 gen_script_tests dc "$extra_math" "$generate_tests" "$time_tests" $dc_test_exec 1598fi 1599 1600cd "$scriptdir" 1601 1602# Copy the correct manuals to the expected places. 1603cp -f manuals/bc/$manpage_args.1.md manuals/bc.1.md 1604cp -f manuals/bc/$manpage_args.1 manuals/bc.1 1605cp -f manuals/dc/$manpage_args.1.md manuals/dc.1.md 1606cp -f manuals/dc/$manpage_args.1 manuals/dc.1 1607 1608make clean > /dev/null 1609