3 # SPDX-License-Identifier: BSD-2-Clause
5 # Copyright (c) 2018-2021 Gavin D. Howard and contributors.
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are met:
10 # * Redistributions of source code must retain the above copyright notice, this
11 # list of conditions and the following disclaimer.
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.
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.
31 scriptdir=$(dirname "$script")
32 script=$(basename "$script")
34 . "$scriptdir/scripts/functions.sh"
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.
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'
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'
172 printf 'In addition, the following environment variables are used:\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'
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'
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'
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'
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'
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'
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'
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'
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.
305 # @param file The filename.
306 # @param ext1 The extension to replace.
307 # @param ext2 The new extension.
310 if [ "$#" -ne 3 ]; then
311 err_exit "Invalid number of args to $0"
314 _replace_ext_file="$1"
315 _replace_ext_ext1="$2"
316 _replace_ext_ext2="$3"
318 _replace_ext_result="${_replace_ext_file%.$_replace_ext_ext1}.$_replace_ext_ext2"
320 printf '%s\n' "$_replace_ext_result"
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()`.
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.
332 if [ "$#" -ne 3 ]; then
333 err_exit "Invalid number of args to $0"
336 _replace_exts_files="$1"
337 _replace_exts_ext1="$2"
338 _replace_exts_ext2="$3"
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"
345 printf '%s\n' "$_replace_exts_result"
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
353 # Note that needle can never contain an exclamation point. For more information,
354 # see substring_replace() in scripts/functions.sh.
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.
361 if [ "$#" -ne 3 ]; then
362 err_exit "Invalid number of args to $0"
367 _replace_replacement="$3"
369 substring_replace "$_replace_str" "%%$_replace_needle%%" "$_replace_replacement"
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.
377 if [ "$#" -ge 1 ] && [ "$1" != "" ]; then
379 while [ "$#" -ge 1 ]; do
380 _find_src_files_a="${1## }"
382 _find_src_files_args="$_find_src_files_args ! -path src/${_find_src_files_a}"
386 _find_src_files_args="-print"
389 printf '%s\n' $(find src/ -depth -name "*.c" $_find_src_files_args)
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.
395 # @param contents The contents of the Makefile template to put the list of
399 if [ "$#" -lt 1 ]; then
400 err_exit "Invalid number of args to $0"
403 _gen_file_list_contents="$1"
410 if [ "$#" -ge 1 ]; then
411 _gen_file_list_unneeded="$@"
413 _gen_file_list_unneeded=""
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"
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")
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")
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")
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")
439 printf '%s\n' "$_gen_file_list_contents"
442 # Generates the proper test targets for each test to have its own target. This
443 # allows `make test` to run in parallel.
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.
451 _gen_std_tests_name="$1"
454 _gen_std_tests_extra_math="$1"
457 _gen_std_tests_time_tests="$1"
460 _gen_std_tests_extra_required=$(cat "$scriptdir/tests/extra_required.txt")
462 for _gen_std_tests_t in $(cat "$scriptdir/tests/$_gen_std_tests_name/all.txt"); do
464 if [ "$_gen_std_tests_extra_math" -eq 0 ]; then
466 if [ -z "${_gen_std_tests_extra_required##*$_gen_std_tests_t*}" ]; then
467 printf 'test_%s_%s:\n\t@printf "Skipping %s %s\\n"\n\n' \
468 "$_gen_std_tests_name" "$_gen_std_tests_t" "$_gen_std_tests_name" \
469 "$_gen_std_tests_t" >> "$scriptdir/Makefile"
475 printf 'test_%s_%s:\n\t@sh tests/test.sh %s %s %s %s %s\n\n' \
476 "$_gen_std_tests_name" "$_gen_std_tests_t" "$_gen_std_tests_name" \
477 "$_gen_std_tests_t" "$generate_tests" "$time_tests" \
478 "$*" >> "$scriptdir/Makefile"
483 # Generates a list of test targets that will be used as prerequisites for other
486 # @param name The name of the calculator to generate test targets for.
487 gen_std_test_targets() {
489 _gen_std_test_targets_name="$1"
492 _gen_std_test_targets_tests=$(cat "$scriptdir/tests/${_gen_std_test_targets_name}/all.txt")
494 for _gen_std_test_targets_t in $_gen_std_test_targets_tests; do
495 printf ' test_%s_%s' "$_gen_std_test_targets_name" "$_gen_std_test_targets_t"
501 # Generates the proper test targets for each error test to have its own target.
502 # This allows `make test_bc_errors` and `make test_dc_errors` to run in
505 # @param name Which calculator to generate tests for.
508 _gen_err_tests_name="$1"
511 _gen_err_tests_fs=$(ls "$scriptdir/tests/$_gen_err_tests_name/errors/")
513 for _gen_err_tests_t in $_gen_err_tests_fs; do
515 printf 'test_%s_error_%s:\n\t@sh tests/error.sh %s %s %s\n\n' \
516 "$_gen_err_tests_name" "$_gen_err_tests_t" "$_gen_err_tests_name" \
517 "$_gen_err_tests_t" "$*" >> "$scriptdir/Makefile"
523 # Generates a list of error test targets that will be used as prerequisites for
526 # @param name The name of the calculator to generate test targets for.
527 gen_err_test_targets() {
529 _gen_err_test_targets_name="$1"
532 _gen_err_test_targets_tests=$(ls "$scriptdir/tests/$_gen_err_test_targets_name/errors/")
534 for _gen_err_test_targets_t in $_gen_err_test_targets_tests; do
535 printf ' test_%s_error_%s' "$_gen_err_test_targets_name" "$_gen_err_test_targets_t"
541 # Generates the proper script test targets for each script test to have its own
542 # target. This allows `make test` to run in parallel.
544 # @param name Which calculator to generate tests for.
545 # @param extra_math An integer that, if non-zero, activates extra math tests.
546 # @param generate An integer that, if non-zero, activates generated tests.
547 # @param time_tests An integer that, if non-zero, tells the test suite to time
548 # the execution of each test.
551 _gen_script_tests_name="$1"
554 _gen_script_tests_extra_math="$1"
557 _gen_script_tests_generate="$1"
560 _gen_script_tests_time="$1"
563 _gen_script_tests_tests=$(cat "$scriptdir/tests/$_gen_script_tests_name/scripts/all.txt")
565 for _gen_script_tests_f in $_gen_script_tests_tests; do
567 _gen_script_tests_b=$(basename "$_gen_script_tests_f" ".${_gen_script_tests_name}")
569 printf 'test_%s_script_%s:\n\t@sh tests/script.sh %s %s %s 1 %s %s %s\n\n' \
570 "$_gen_script_tests_name" "$_gen_script_tests_b" "$_gen_script_tests_name" \
571 "$_gen_script_tests_f" "$_gen_script_tests_extra_math" "$_gen_script_tests_generate" \
572 "$_gen_script_tests_time" "$*" >> "$scriptdir/Makefile"
581 _set_default_name="$1"
584 # The reason that the variables that are being set do not have the same
585 # non-collision avoidance that the other variables do is that we *do* want
586 # the settings of these variables to leak out of the function. They adjust
587 # the settings outside of the function.
588 case "$_set_default_name" in
590 bc.banner) bc_default_banner="$_set_default_on" ;;
591 bc.sigint_reset) bc_default_sigint_reset="$_set_default_on" ;;
592 dc.sigint_reset) dc_default_sigint_reset="$_set_default_on" ;;
593 bc.tty_mode) bc_default_tty_mode="$_set_default_on" ;;
594 dc.tty_mode) dc_default_tty_mode="$_set_default_on" ;;
595 bc.prompt) bc_default_prompt="$_set_default_on" ;;
596 dc.prompt) dc_default_prompt="$_set_default_on" ;;
597 ?) usage "Invalid setting: $_set_default_name" ;;
602 # Generates a list of script test targets that will be used as prerequisites for
605 # @param name The name of the calculator to generate script test targets for.
606 gen_script_test_targets() {
608 _gen_script_test_targets_name="$1"
611 _gen_script_test_targets_tests=$(cat "$scriptdir/tests/$_gen_script_test_targets_name/scripts/all.txt")
613 for _gen_script_test_targets_f in $_gen_script_test_targets_tests; do
614 _gen_script_test_targets_b=$(basename "$_gen_script_test_targets_f" \
615 ".$_gen_script_test_targets_name")
616 printf ' test_%s_script_%s' "$_gen_script_test_targets_name" \
617 "$_gen_script_test_targets_b"
623 # This is a list of defaults, but it is also the list of possible options for
626 # The development options are: force (force options even if they fail), valgrind
627 # (build in a way suitable for valgrind testing), memcheck (same as valgrind),
628 # and fuzzing (build in a way suitable for fuzzing).
650 # The empty strings are because they depend on TTY mode. If they are directly
651 # set, though, they will be integers. We test for empty strings later.
653 bc_default_sigint_reset=1
654 dc_default_sigint_reset=1
655 bc_default_tty_mode=1
656 dc_default_tty_mode=0
660 # getopts is a POSIX utility, but it cannot handle long options. Thus, the
661 # handling of long options is done by hand, and that's the reason that short and
662 # long options cannot be mixed.
663 while getopts "abBcdDEfgGhHk:lMmNO:S:s:tTvz-" opt; do
676 G) generate_tests=0 ;;
679 k) karatsuba_len="$OPTARG" ;;
682 M) install_manpages=0 ;;
684 O) optimization="$OPTARG" ;;
685 S) set_default 0 "$OPTARG" ;;
686 s) set_default 1 "$OPTARG" ;;
694 LONG_OPTARG="${arg#*=}"
697 library) library=1 ;;
698 bc-only) bc_only=1 ;;
699 dc-only) dc_only=1 ;;
700 coverage) coverage=1 ;;
703 prefix=?*) PREFIX="$LONG_OPTARG" ;;
705 if [ "$#" -lt 2 ]; then
706 usage "No argument given for '--$arg' option"
710 bindir=?*) BINDIR="$LONG_OPTARG" ;;
712 if [ "$#" -lt 2 ]; then
713 usage "No argument given for '--$arg' option"
717 includedir=?*) INCLUDEDIR="$LONG_OPTARG" ;;
719 if [ "$#" -lt 2 ]; then
720 usage "No argument given for '--$arg' option"
724 libdir=?*) LIBDIR="$LONG_OPTARG" ;;
726 if [ "$#" -lt 2 ]; then
727 usage "No argument given for '--$arg' option"
731 datarootdir=?*) DATAROOTDIR="$LONG_OPTARG" ;;
733 if [ "$#" -lt 2 ]; then
734 usage "No argument given for '--$arg' option"
738 datadir=?*) DATADIR="$LONG_OPTARG" ;;
740 if [ "$#" -lt 2 ]; then
741 usage "No argument given for '--$arg' option"
745 mandir=?*) MANDIR="$LONG_OPTARG" ;;
747 if [ "$#" -lt 2 ]; then
748 usage "No argument given for '--$arg' option"
752 man1dir=?*) MAN1DIR="$LONG_OPTARG" ;;
754 if [ "$#" -lt 2 ]; then
755 usage "No argument given for '--$arg' option"
759 man3dir=?*) MAN3DIR="$LONG_OPTARG" ;;
761 if [ "$#" -lt 2 ]; then
762 usage "No argument given for '--$arg' option"
766 localedir=?*) LOCALEDIR="$LONG_OPTARG" ;;
768 if [ "$#" -lt 2 ]; then
769 usage "No argument given for '--$arg' option"
773 karatsuba-len=?*) karatsuba_len="$LONG_OPTARG" ;;
775 if [ "$#" -lt 2 ]; then
776 usage "No argument given for '--$arg' option"
780 opt=?*) optimization="$LONG_OPTARG" ;;
782 if [ "$#" -lt 2 ]; then
783 usage "No argument given for '--$arg' option"
787 set-default-on=?*) set_default 1 "$LONG_OPTARG" ;;
789 if [ "$#" -lt 2 ]; then
790 usage "No argument given for '--$arg' option"
794 set-default-off=?*) set_default 0 "$LONG_OPTARG" ;;
796 if [ "$#" -lt 2 ]; then
797 usage "No argument given for '--$arg' option"
801 disable-bc) dc_only=1 ;;
802 disable-dc) bc_only=1 ;;
803 disable-clean) clean=0 ;;
804 disable-extra-math) extra_math=0 ;;
805 disable-generated-tests) generate_tests=0 ;;
806 disable-history) hist=0 ;;
807 disable-man-pages) install_manpages=0 ;;
808 disable-nls) nls=0 ;;
809 disable-strip) strip_bin=0 ;;
810 enable-test-timing) time_tests=1 ;;
811 enable-valgrind) vg=1 ;;
812 enable-fuzz-mode) fuzz=1 ;;
813 enable-memcheck) memcheck=1 ;;
814 install-all-locales) all_locales=1 ;;
815 help* | bc-only* | dc-only* | coverage* | debug*)
816 usage "No arg allowed for --$arg option" ;;
817 disable-bc* | disable-dc* | disable-clean*)
818 usage "No arg allowed for --$arg option" ;;
820 usage "No arg allowed for --$arg option" ;;
821 disable-generated-tests* | disable-history*)
822 usage "No arg allowed for --$arg option" ;;
823 disable-man-pages* | disable-nls* | disable-strip*)
824 usage "No arg allowed for --$arg option" ;;
825 enable-fuzz-mode* | enable-test-timing* | enable-valgrind*)
826 usage "No arg allowed for --$arg option" ;;
827 enable-memcheck* | install-all-locales*)
828 usage "No arg allowed for --$arg option" ;;
829 '') break ;; # "--" terminates argument processing
830 * ) usage "Invalid option $LONG_OPTARG" ;;
834 ?) usage "Invalid option: $opt" ;;
839 # Sometimes, developers don't want configure.sh to do a config clean. But
841 if [ "$clean" -ne 0 ]; then
842 if [ -f ./Makefile ]; then
843 make clean_config > /dev/null
847 # It is an error to say that bc only should be built and likewise for dc.
848 if [ "$bc_only" -eq 1 ] && [ "$dc_only" -eq 1 ]; then
849 usage "Can only specify one of -b(-D) or -d(-B)"
852 # The library is mutually exclusive to the calculators, so it's an error to
853 # give an option for either of them.
854 if [ "$library" -ne 0 ]; then
855 if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then
856 usage "Must not specify -b(-D) or -d(-B) when building the library"
860 # KARATSUBA_LEN must be an integer and must be 16 or greater.
861 case $karatsuba_len in
862 (*[!0-9]*|'') usage "KARATSUBA_LEN is not a number" ;;
866 if [ "$karatsuba_len" -lt 16 ]; then
867 usage "KARATSUBA_LEN is less than 16"
872 if [ -z "${LONG_BIT+set}" ]; then
874 elif [ "$LONG_BIT" -lt 32 ]; then
875 usage "LONG_BIT is less than 32"
877 LONG_BIT_DEFINE="-DBC_LONG_BIT=\$(BC_LONG_BIT)"
880 if [ -z "$CC" ]; then
884 # I had users complain that, if they gave CFLAGS as part of CC, which
885 # autotools allows in its braindead way, the build would fail with an error.
886 # I don't like adjusting for autotools, but oh well. These lines puts the
887 # stuff after the first space into CFLAGS.
888 ccbase=$(basename "$CC")
892 if [ "${ccbase%%$suffix}" != "$ccbase" ]; then
893 ccflags="${ccbase#$prefix}"
894 cc="${ccbase%%$suffix}"
895 ccdir=$(dirname "$CC")
896 if [ "$ccdir" = "." ] && [ "${CC#.}" = "$CC" ]; then
902 CFLAGS="$CFLAGS $ccflags"
906 if [ -z "$HOSTCC" ] && [ -z "$HOST_CC" ]; then
908 elif [ -z "$HOSTCC" ]; then
912 if [ "$HOSTCC" != "$CC" ]; then
914 # Like above, this splits HOSTCC and HOSTCFLAGS.
915 ccbase=$(basename "$HOSTCC")
919 if [ "${ccbase%%$suffix}" != "$ccbase" ]; then
920 ccflags="${ccbase#$prefix}"
921 cc="${ccbase%%$suffix}"
922 ccdir=$(dirname "$HOSTCC")
923 if [ "$ccdir" = "." ] && [ "${HOSTCC#.}" = "$HOSTCC" ]; then
928 HOSTCC="${ccdir}${cc}"
929 HOSTCFLAGS="$HOSTCFLAGS $ccflags"
933 if [ -z "${HOSTCFLAGS+set}" ] && [ -z "${HOST_CFLAGS+set}" ]; then
935 elif [ -z "${HOSTCFLAGS+set}" ]; then
936 HOSTCFLAGS="$HOST_CFLAGS"
939 # Store these for the cross compilation detection later.
941 OLDHOSTCFLAGS="$HOSTCFLAGS"
943 link="@printf 'No link necessary\\\\n'"
947 tests="test_bc timeconst test_dc"
949 bc_test="@tests/all.sh bc $extra_math 1 $generate_tests $time_tests \$(BC_EXEC)"
950 bc_test_np="@tests/all.sh -n bc $extra_math 1 $generate_tests $time_tests \$(BC_EXEC)"
951 dc_test="@tests/all.sh dc $extra_math 1 $generate_tests $time_tests \$(DC_EXEC)"
952 dc_test_np="@tests/all.sh -n dc $extra_math 1 $generate_tests $time_tests \$(DC_EXEC)"
954 timeconst="@tests/bc/timeconst.sh tests/bc/scripts/timeconst.bc \$(BC_EXEC)"
956 # In order to have cleanup at exit, we need to be in
957 # debug mode, so don't run valgrind without that.
958 if [ "$vg" -ne 0 ]; then
960 bc_test_exec='valgrind $(VALGRIND_ARGS) $(BC_EXEC)'
961 dc_test_exec='valgrind $(VALGRIND_ARGS) $(DC_EXEC)'
963 bc_test_exec='$(BC_EXEC)'
964 dc_test_exec='$(DC_EXEC)'
967 test_bc_history_prereqs="test_bc_history_all"
968 test_dc_history_prereqs="test_dc_history_all"
970 karatsuba="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
971 karatsuba_test="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
973 bc_lib="\$(GEN_DIR)/lib.o"
974 bc_help="\$(GEN_DIR)/bc_help.o"
975 dc_help="\$(GEN_DIR)/dc_help.o"
977 default_target_prereqs="\$(BIN) \$(OBJS)"
978 default_target_cmd="\$(CC) \$(CFLAGS) \$(OBJS) \$(LDFLAGS) -o \$(EXEC)"
979 default_target="\$(DC_EXEC)"
981 second_target_prereqs=""
982 second_target_cmd="$default_target_cmd"
983 second_target="\$(BC_EXEC)"
985 # This if/else if chain is for setting the defaults that change based on whether
986 # the library is being built, bc only, dc only, or both calculators.
987 if [ "$library" -ne 0 ]; then
995 default_target_prereqs="\$(BIN) \$(OBJ)"
996 default_target_cmd="ar -r -cu \$(LIBBC) \$(OBJ)"
997 default_target="\$(LIBBC)"
999 test_bc_history_prereqs=" test_bc_history_skip"
1000 test_dc_history_prereqs=" test_dc_history_skip"
1002 elif [ "$bc_only" -eq 1 ]; then
1011 dc_test="@printf 'No dc tests to run\\\\n'"
1012 dc_test_np="@printf 'No dc tests to run\\\\n'"
1013 test_dc_history_prereqs=" test_dc_history_skip"
1015 install_prereqs=" install_execs"
1016 install_man_prereqs=" install_bc_manpage"
1017 uninstall_prereqs=" uninstall_bc"
1018 uninstall_man_prereqs=" uninstall_bc_manpage"
1020 default_target="\$(BC_EXEC)"
1021 second_target="\$(DC_EXEC)"
1022 tests="test_bc timeconst"
1024 elif [ "$dc_only" -eq 1 ]; then
1035 executable="DC_EXEC"
1037 bc_test="@printf 'No bc tests to run\\\\n'"
1038 bc_test_np="@printf 'No bc tests to run\\\\n'"
1039 test_bc_history_prereqs=" test_bc_history_skip"
1041 timeconst="@printf 'timeconst cannot be run because bc is not built\\\\n'"
1043 install_prereqs=" install_execs"
1044 install_man_prereqs=" install_dc_manpage"
1045 uninstall_prereqs=" uninstall_dc"
1046 uninstall_man_prereqs=" uninstall_dc_manpage"
1055 executables="bc and dc"
1057 karatsuba="@\$(KARATSUBA) 30 0 \$(BC_EXEC)"
1058 karatsuba_test="@\$(KARATSUBA) 1 100 \$(BC_EXEC)"
1060 if [ "$library" -eq 0 ]; then
1061 install_prereqs=" install_execs"
1062 install_man_prereqs=" install_bc_manpage install_dc_manpage"
1063 uninstall_prereqs=" uninstall_bc uninstall_dc"
1064 uninstall_man_prereqs=" uninstall_bc_manpage uninstall_dc_manpage"
1066 install_prereqs=" install_library install_bcl_header"
1067 install_man_prereqs=" install_bcl_manpage"
1068 uninstall_prereqs=" uninstall_library uninstall_bcl_header"
1069 uninstall_man_prereqs=" uninstall_bcl_manpage"
1070 tests="test_library"
1073 second_target_prereqs="$default_target_prereqs"
1074 default_target_prereqs="$second_target"
1075 default_target_cmd="\$(LINK) \$(BIN) \$(EXEC_PREFIX)\$(DC)"
1079 # We need specific stuff for fuzzing.
1080 if [ "$fuzz" -ne 0 ]; then
1087 # This sets some necessary things for debug mode.
1088 if [ "$debug" -eq 1 ]; then
1090 if [ -z "$CFLAGS" ] && [ -z "$optimization" ]; then
1098 CPPFLAGS="-DNDEBUG $CPPFLAGS"
1100 if [ "$strip_bin" -ne 0 ]; then
1101 LDFLAGS="-s $LDFLAGS"
1105 # Set optimization CFLAGS.
1106 if [ -n "$optimization" ]; then
1107 CFLAGS="-O$optimization $CFLAGS"
1110 # Set test coverage defaults.
1111 if [ "$coverage" -eq 1 ]; then
1113 if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then
1114 usage "Can only specify -c without -b or -d"
1117 CFLAGS="-fprofile-arcs -ftest-coverage -g -O0 $CFLAGS"
1118 CPPFLAGS="-DNDEBUG $CPPFLAGS"
1120 COVERAGE_OUTPUT="@gcov -pabcdf \$(GCDA) \$(BC_GCDA) \$(DC_GCDA) \$(HISTORY_GCDA) \$(RAND_GCDA)"
1121 COVERAGE_OUTPUT="$COVERAGE_OUTPUT;\$(RM) -f \$(GEN)*.gc*"
1122 COVERAGE_OUTPUT="$COVERAGE_OUTPUT;gcovr --exclude-unreachable-branches --exclude-throw-branches --html-details --output index.html"
1123 COVERAGE_PREREQS=" test coverage_output"
1126 COVERAGE_OUTPUT="@printf 'Coverage not generated\\\\n'"
1131 # Set some defaults.
1132 if [ -z "${DESTDIR+set}" ]; then
1135 destdir="DESTDIR = $DESTDIR"
1138 if [ -z "${PREFIX+set}" ]; then
1142 if [ -z "${BINDIR+set}" ]; then
1143 BINDIR="$PREFIX/bin"
1146 if [ -z "${INCLUDEDIR+set}" ]; then
1147 INCLUDEDIR="$PREFIX/include"
1150 if [ -z "${LIBDIR+set}" ]; then
1151 LIBDIR="$PREFIX/lib"
1154 # Set a default for the DATAROOTDIR. This is done if either manpages will be
1155 # installed, or locales are enabled because that's probably where NLS_PATH
1157 if [ "$install_manpages" -ne 0 ] || [ "$nls" -ne 0 ]; then
1158 if [ -z "${DATAROOTDIR+set}" ]; then
1159 DATAROOTDIR="$PREFIX/share"
1163 # Set defaults for manpage environment variables.
1164 if [ "$install_manpages" -ne 0 ]; then
1166 if [ -z "${DATADIR+set}" ]; then
1167 DATADIR="$DATAROOTDIR"
1170 if [ -z "${MANDIR+set}" ]; then
1171 MANDIR="$DATADIR/man"
1174 if [ -z "${MAN1DIR+set}" ]; then
1175 MAN1DIR="$MANDIR/man1"
1178 if [ -z "${MAN3DIR+set}" ]; then
1179 MAN3DIR="$MANDIR/man3"
1183 install_man_prereqs=""
1184 uninstall_man_prereqs=""
1187 # Here is where we test NLS (the locale system). This is done by trying to
1188 # compile src/vm.c, which has the relevant code. If it fails, then it is
1190 if [ "$nls" -ne 0 ]; then
1194 printf 'Testing NLS...\n'
1196 flags="-DBC_ENABLE_NLS=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
1197 flags="$flags -DBC_ENABLE_HISTORY=$hist -DBC_ENABLE_LIBRARY=0 -DBC_ENABLE_AFL=0"
1198 flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/"
1199 flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
1201 "$CC" $CPPFLAGS $CFLAGS $flags -c "src/vm.c" -o "$scriptdir/vm.o" > /dev/null 2>&1
1205 rm -rf "$scriptdir/vm.o"
1207 # If this errors, it is probably because of building on Windows,
1208 # and NLS is not supported on Windows, so disable it.
1209 if [ "$err" -ne 0 ]; then
1210 printf 'NLS does not work.\n'
1211 if [ $force -eq 0 ]; then
1212 printf 'Disabling NLS...\n\n'
1215 printf 'Forcing NLS...\n\n'
1218 printf 'NLS works.\n\n'
1220 printf 'Testing gencat...\n'
1221 gencat "$scriptdir/en_US.cat" "$scriptdir/locales/en_US.msg" > /dev/null 2>&1
1225 rm -rf "$scriptdir/en_US.cat"
1227 if [ "$err" -ne 0 ]; then
1228 printf 'gencat does not work.\n'
1229 if [ $force -eq 0 ]; then
1230 printf 'Disabling NLS...\n\n'
1233 printf 'Forcing NLS...\n\n'
1237 printf 'gencat works.\n\n'
1239 # It turns out that POSIX locales are really terrible, and running
1240 # gencat on one machine is not guaranteed to make those cat files
1241 # portable to another machine, so we had better warn the user here.
1242 if [ "$HOSTCC" != "$CC" ] || [ "$OLDHOSTCFLAGS" != "$OLDCFLAGS" ]; then
1243 printf 'Cross-compile detected.\n\n'
1244 printf 'WARNING: Catalog files generated with gencat may not be portable\n'
1245 printf ' across different architectures.\n\n'
1248 if [ -z "$NLSPATH" ]; then
1249 NLSPATH="/usr/share/locale/%L/%N"
1252 install_locales_prereqs=" install_locales"
1253 uninstall_locales_prereqs=" uninstall_locales"
1262 install_locales_prereqs=""
1263 uninstall_locales_prereqs=""
1267 if [ "$nls" -ne 0 ] && [ "$all_locales" -ne 0 ]; then
1268 install_locales="\$(LOCALE_INSTALL) -l \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)"
1270 install_locales="\$(LOCALE_INSTALL) \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)"
1273 # Like the above tested locale support, this tests history.
1274 if [ "$hist" -eq 1 ]; then
1278 printf 'Testing history...\n'
1280 flags="-DBC_ENABLE_HISTORY=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
1281 flags="$flags -DBC_ENABLE_NLS=$nls -DBC_ENABLE_LIBRARY=0 -DBC_ENABLE_AFL=0"
1282 flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/"
1283 flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
1285 "$CC" $CPPFLAGS $CFLAGS $flags -c "src/history.c" -o "$scriptdir/history.o" > /dev/null 2>&1
1289 rm -rf "$scriptdir/history.o"
1291 # If this errors, it is probably because of building on Windows,
1292 # and history is not supported on Windows, so disable it.
1293 if [ "$err" -ne 0 ]; then
1294 printf 'History does not work.\n'
1295 if [ $force -eq 0 ]; then
1296 printf 'Disabling history...\n\n'
1299 printf 'Forcing history...\n\n'
1302 printf 'History works.\n\n'
1309 # We have to disable the history tests if it is disabled or valgrind is on.
1310 if [ "$hist" -eq 0 ] || [ "$vg" -ne 0 ]; then
1311 test_bc_history_prereqs=" test_bc_history_skip"
1312 test_dc_history_prereqs=" test_dc_history_skip"
1313 history_tests="@printf 'Skipping history tests...\\\\n'"
1315 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'"
1318 # Test OpenBSD. This is not in an if statement because regardless of whatever
1319 # the user says, we need to know if we are on OpenBSD to activate _BSD_SOURCE.
1320 # No, I cannot `#define _BSD_SOURCE` in a header because OpenBSD's patched GCC
1321 # and Clang complain that that is only allowed for system headers. Sigh....So we
1322 # have to check at configure time and set it on the compiler command-line. And
1323 # we have to set it because we also set _POSIX_C_SOURCE, which OpenBSD headers
1324 # detect, and when they detect it, they turn off _BSD_SOURCE unless it is
1325 # specifically requested.
1327 printf 'Testing for OpenBSD...\n'
1329 flags="-DBC_TEST_OPENBSD -DBC_ENABLE_AFL=0"
1330 "$CC" $CPPFLAGS $CFLAGS $flags -I./include -E "include/status.h" > /dev/null 2>&1
1334 if [ "$err" -ne 0 ]; then
1335 printf 'On OpenBSD. Using _BSD_SOURCE.\n\n'
1338 printf 'Not on OpenBSD.\n\n'
1342 if [ "$library" -eq 1 ]; then
1346 if [ "$extra_math" -eq 1 ] && [ "$bc" -ne 0 ] && [ "$library" -eq 0 ]; then
1347 BC_LIB2_O="\$(GEN_DIR)/lib2.o"
1352 # These lines set the appropriate targets based on whether `gen/strgen.c` or
1353 # `gen/strgen.sh` is used.
1355 GEN_EXEC_TARGET="\$(HOSTCC) \$(HOSTCFLAGS) -o \$(GEN_EXEC) \$(GEN_C)"
1356 CLEAN_PREREQS=" clean_gen clean_coverage"
1358 if [ -z "${GEN_HOST+set}" ]; then
1361 if [ "$GEN_HOST" -eq 0 ]; then
1363 GEN_EXEC_TARGET="@printf 'Do not need to build gen/strgen.c\\\\n'"
1364 CLEAN_PREREQS=" clean_coverage"
1370 headers="\$(HEADERS)"
1372 # This series of if statements figure out what source files are *not* needed.
1373 if [ "$extra_math" -eq 0 ]; then
1375 unneeded="$unneeded rand.c"
1377 headers="$headers \$(EXTRA_MATH_HEADERS)"
1380 # All of these next if statements set the build type and mark certain source
1381 # files as unneeded so that they won't have targets generated for them.
1383 if [ "$hist" -eq 0 ]; then
1384 manpage_args="${manpage_args}H"
1385 unneeded="$unneeded history.c"
1387 headers="$headers \$(HISTORY_HEADERS)"
1390 if [ "$nls" -eq 0 ]; then
1391 manpage_args="${manpage_args}N"
1394 if [ "$bc" -eq 0 ]; then
1395 unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
1397 headers="$headers \$(BC_HEADERS)"
1400 if [ "$dc" -eq 0 ]; then
1401 unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
1403 headers="$headers \$(DC_HEADERS)"
1406 if [ "$library" -ne 0 ]; then
1407 unneeded="$unneeded args.c opt.c read.c file.c main.c"
1408 unneeded="$unneeded lang.c lex.c parse.c program.c"
1409 unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
1410 unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
1411 headers="$headers \$(LIBRARY_HEADERS)"
1413 unneeded="$unneeded library.c"
1416 # library.c is not needed under normal circumstances.
1417 if [ "$unneeded" = "" ]; then
1418 unneeded="library.c"
1421 # This sets the appropriate manpage for a full build.
1422 if [ "$manpage_args" = "" ]; then
1426 if [ "$vg" -ne 0 ]; then
1430 if [ "$bc_default_prompt" = "" ]; then
1431 bc_default_prompt="$bc_default_tty_mode"
1434 if [ "$dc_default_prompt" = "" ]; then
1435 dc_default_prompt="$dc_default_tty_mode"
1438 # Generate the test targets and prerequisites.
1439 bc_tests=$(gen_std_test_targets bc)
1440 bc_script_tests=$(gen_script_test_targets bc)
1441 bc_err_tests=$(gen_err_test_targets bc)
1442 dc_tests=$(gen_std_test_targets dc)
1443 dc_script_tests=$(gen_script_test_targets dc)
1444 dc_err_tests=$(gen_err_test_targets dc)
1446 # Print out the values; this is for debugging.
1447 if [ "$bc" -ne 0 ]; then
1448 printf 'Building bc\n'
1450 printf 'Not building bc\n'
1452 if [ "$dc" -ne 0 ]; then
1453 printf 'Building dc\n'
1455 printf 'Not building dc\n'
1458 printf 'BC_ENABLE_LIBRARY=%s\n\n' "$library"
1459 printf 'BC_ENABLE_HISTORY=%s\n' "$hist"
1460 printf 'BC_ENABLE_EXTRA_MATH=%s\n' "$extra_math"
1461 printf 'BC_ENABLE_NLS=%s\n' "$nls"
1462 printf 'BC_ENABLE_AFL=%s\n' "$fuzz"
1464 printf 'BC_NUM_KARATSUBA_LEN=%s\n' "$karatsuba_len"
1466 printf 'CC=%s\n' "$CC"
1467 printf 'CFLAGS=%s\n' "$CFLAGS"
1468 printf 'HOSTCC=%s\n' "$HOSTCC"
1469 printf 'HOSTCFLAGS=%s\n' "$HOSTCFLAGS"
1470 printf 'CPPFLAGS=%s\n' "$CPPFLAGS"
1471 printf 'LDFLAGS=%s\n' "$LDFLAGS"
1472 printf 'PREFIX=%s\n' "$PREFIX"
1473 printf 'BINDIR=%s\n' "$BINDIR"
1474 printf 'INCLUDEDIR=%s\n' "$INCLUDEDIR"
1475 printf 'LIBDIR=%s\n' "$LIBDIR"
1476 printf 'DATAROOTDIR=%s\n' "$DATAROOTDIR"
1477 printf 'DATADIR=%s\n' "$DATADIR"
1478 printf 'MANDIR=%s\n' "$MANDIR"
1479 printf 'MAN1DIR=%s\n' "$MAN1DIR"
1480 printf 'MAN3DIR=%s\n' "$MAN3DIR"
1481 printf 'NLSPATH=%s\n' "$NLSPATH"
1482 printf 'EXECSUFFIX=%s\n' "$EXECSUFFIX"
1483 printf 'EXECPREFIX=%s\n' "$EXECPREFIX"
1484 printf 'DESTDIR=%s\n' "$DESTDIR"
1485 printf 'LONG_BIT=%s\n' "$LONG_BIT"
1486 printf 'GEN_HOST=%s\n' "$GEN_HOST"
1487 printf 'GEN_EMU=%s\n' "$GEN_EMU"
1489 printf 'Setting Defaults\n'
1490 printf '================\n'
1491 printf 'bc.banner=%s\n' "$bc_default_banner"
1492 printf 'bc.sigint_reset=%s\n' "$bc_default_sigint_reset"
1493 printf 'dc.sigint_reset=%s\n' "$dc_default_sigint_reset"
1494 printf 'bc.tty_mode=%s\n' "$bc_default_tty_mode"
1495 printf 'dc.tty_mode=%s\n' "$dc_default_tty_mode"
1496 printf 'bc.prompt=%s\n' "$bc_default_prompt"
1497 printf 'dc.prompt=%s\n' "$dc_default_prompt"
1499 # This is where the real work begins. This is the point at which the Makefile.in
1500 # template is edited and output to the Makefile.
1502 contents=$(cat "$scriptdir/Makefile.in")
1505 replacement='*** WARNING: Autogenerated from Makefile.in. DO NOT MODIFY ***'
1507 contents=$(replace "$contents" "$needle" "$replacement")
1509 # The contents are edited to have the list of files to build.
1510 contents=$(gen_file_list "$contents" $unneeded)
1514 # This line and loop generates the individual targets for source files. I used
1515 # to just use an implicit target, but that was found to be inadequate when I
1516 # added the library.
1517 src_files=$(find_src_files $unneeded)
1519 for f in $src_files; do
1520 o=$(replace_ext "$f" "c" "o")
1521 SRC_TARGETS=$(printf '%s\n\n%s: %s %s\n\t$(CC) $(CFLAGS) -o %s -c %s\n' \
1522 "$SRC_TARGETS" "$o" "$headers" "$f" "$o" "$f")
1525 # Replace all the placeholders.
1526 contents=$(replace "$contents" "HEADERS" "$headers")
1528 contents=$(replace "$contents" "BC_ENABLED" "$bc")
1529 contents=$(replace "$contents" "DC_ENABLED" "$dc")
1531 contents=$(replace "$contents" "BC_ALL_TESTS" "$bc_test")
1532 contents=$(replace "$contents" "BC_ALL_TESTS_NP" "$bc_test_np")
1533 contents=$(replace "$contents" "BC_TESTS" "$bc_tests")
1534 contents=$(replace "$contents" "BC_SCRIPT_TESTS" "$bc_script_tests")
1535 contents=$(replace "$contents" "BC_ERROR_TESTS" "$bc_err_tests")
1536 contents=$(replace "$contents" "BC_TEST_EXEC" "$bc_test_exec")
1537 contents=$(replace "$contents" "TIMECONST_ALL_TESTS" "$timeconst")
1539 contents=$(replace "$contents" "DC_ALL_TESTS" "$dc_test")
1540 contents=$(replace "$contents" "DC_ALL_TESTS_NP" "$dc_test_np")
1541 contents=$(replace "$contents" "DC_TESTS" "$dc_tests")
1542 contents=$(replace "$contents" "DC_SCRIPT_TESTS" "$dc_script_tests")
1543 contents=$(replace "$contents" "DC_ERROR_TESTS" "$dc_err_tests")
1544 contents=$(replace "$contents" "DC_TEST_EXEC" "$dc_test_exec")
1546 contents=$(replace "$contents" "BUILD_TYPE" "$manpage_args")
1548 contents=$(replace "$contents" "LIBRARY" "$library")
1549 contents=$(replace "$contents" "HISTORY" "$hist")
1550 contents=$(replace "$contents" "EXTRA_MATH" "$extra_math")
1551 contents=$(replace "$contents" "NLS" "$nls")
1552 contents=$(replace "$contents" "FUZZ" "$fuzz")
1553 contents=$(replace "$contents" "MEMCHECK" "$memcheck")
1555 contents=$(replace "$contents" "BC_LIB_O" "$bc_lib")
1556 contents=$(replace "$contents" "BC_HELP_O" "$bc_help")
1557 contents=$(replace "$contents" "DC_HELP_O" "$dc_help")
1558 contents=$(replace "$contents" "BC_LIB2_O" "$BC_LIB2_O")
1559 contents=$(replace "$contents" "KARATSUBA_LEN" "$karatsuba_len")
1561 contents=$(replace "$contents" "NLSPATH" "$NLSPATH")
1562 contents=$(replace "$contents" "DESTDIR" "$destdir")
1563 contents=$(replace "$contents" "EXECSUFFIX" "$EXECSUFFIX")
1564 contents=$(replace "$contents" "EXECPREFIX" "$EXECPREFIX")
1565 contents=$(replace "$contents" "BINDIR" "$BINDIR")
1566 contents=$(replace "$contents" "INCLUDEDIR" "$INCLUDEDIR")
1567 contents=$(replace "$contents" "LIBDIR" "$LIBDIR")
1568 contents=$(replace "$contents" "MAN1DIR" "$MAN1DIR")
1569 contents=$(replace "$contents" "MAN3DIR" "$MAN3DIR")
1570 contents=$(replace "$contents" "CFLAGS" "$CFLAGS")
1571 contents=$(replace "$contents" "HOSTCFLAGS" "$HOSTCFLAGS")
1572 contents=$(replace "$contents" "CPPFLAGS" "$CPPFLAGS")
1573 contents=$(replace "$contents" "LDFLAGS" "$LDFLAGS")
1574 contents=$(replace "$contents" "CC" "$CC")
1575 contents=$(replace "$contents" "HOSTCC" "$HOSTCC")
1576 contents=$(replace "$contents" "COVERAGE_OUTPUT" "$COVERAGE_OUTPUT")
1577 contents=$(replace "$contents" "COVERAGE_PREREQS" "$COVERAGE_PREREQS")
1578 contents=$(replace "$contents" "INSTALL_PREREQS" "$install_prereqs")
1579 contents=$(replace "$contents" "INSTALL_MAN_PREREQS" "$install_man_prereqs")
1580 contents=$(replace "$contents" "INSTALL_LOCALES" "$install_locales")
1581 contents=$(replace "$contents" "INSTALL_LOCALES_PREREQS" "$install_locales_prereqs")
1582 contents=$(replace "$contents" "UNINSTALL_MAN_PREREQS" "$uninstall_man_prereqs")
1583 contents=$(replace "$contents" "UNINSTALL_PREREQS" "$uninstall_prereqs")
1584 contents=$(replace "$contents" "UNINSTALL_LOCALES_PREREQS" "$uninstall_locales_prereqs")
1586 contents=$(replace "$contents" "DEFAULT_TARGET" "$default_target")
1587 contents=$(replace "$contents" "DEFAULT_TARGET_PREREQS" "$default_target_prereqs")
1588 contents=$(replace "$contents" "DEFAULT_TARGET_CMD" "$default_target_cmd")
1589 contents=$(replace "$contents" "SECOND_TARGET" "$second_target")
1590 contents=$(replace "$contents" "SECOND_TARGET_PREREQS" "$second_target_prereqs")
1591 contents=$(replace "$contents" "SECOND_TARGET_CMD" "$second_target_cmd")
1593 contents=$(replace "$contents" "ALL_PREREQ" "$ALL_PREREQ")
1594 contents=$(replace "$contents" "BC_EXEC_PREREQ" "$bc_exec_prereq")
1595 contents=$(replace "$contents" "BC_EXEC_CMD" "$bc_exec_cmd")
1596 contents=$(replace "$contents" "DC_EXEC_PREREQ" "$dc_exec_prereq")
1597 contents=$(replace "$contents" "DC_EXEC_CMD" "$dc_exec_cmd")
1599 contents=$(replace "$contents" "EXECUTABLES" "$executables")
1600 contents=$(replace "$contents" "MAIN_EXEC" "$main_exec")
1601 contents=$(replace "$contents" "EXEC" "$executable")
1602 contents=$(replace "$contents" "TESTS" "$tests")
1604 contents=$(replace "$contents" "BC_HISTORY_TEST_PREREQS" "$test_bc_history_prereqs")
1605 contents=$(replace "$contents" "DC_HISTORY_TEST_PREREQS" "$test_dc_history_prereqs")
1606 contents=$(replace "$contents" "HISTORY_TESTS" "$history_tests")
1608 contents=$(replace "$contents" "VG_BC_TEST" "$vg_bc_test")
1609 contents=$(replace "$contents" "VG_DC_TEST" "$vg_dc_test")
1611 contents=$(replace "$contents" "TIMECONST" "$timeconst")
1613 contents=$(replace "$contents" "KARATSUBA" "$karatsuba")
1614 contents=$(replace "$contents" "KARATSUBA_TEST" "$karatsuba_test")
1616 contents=$(replace "$contents" "LONG_BIT" "$LONG_BIT")
1617 contents=$(replace "$contents" "LONG_BIT_DEFINE" "$LONG_BIT_DEFINE")
1619 contents=$(replace "$contents" "GEN" "$GEN")
1620 contents=$(replace "$contents" "GEN_EXEC_TARGET" "$GEN_EXEC_TARGET")
1621 contents=$(replace "$contents" "CLEAN_PREREQS" "$CLEAN_PREREQS")
1622 contents=$(replace "$contents" "GEN_EMU" "$GEN_EMU")
1624 contents=$(replace "$contents" "BSD" "$bsd")
1626 contents=$(replace "$contents" "BC_DEFAULT_BANNER" "$bc_default_banner")
1627 contents=$(replace "$contents" "BC_DEFAULT_SIGINT_RESET" "$bc_default_sigint_reset")
1628 contents=$(replace "$contents" "DC_DEFAULT_SIGINT_RESET" "$dc_default_sigint_reset")
1629 contents=$(replace "$contents" "BC_DEFAULT_TTY_MODE" "$bc_default_tty_mode")
1630 contents=$(replace "$contents" "DC_DEFAULT_TTY_MODE" "$dc_default_tty_mode")
1631 contents=$(replace "$contents" "BC_DEFAULT_PROMPT" "$bc_default_prompt")
1632 contents=$(replace "$contents" "DC_DEFAULT_PROMPT" "$dc_default_prompt")
1634 # Do the first print to the Makefile.
1635 printf '%s\n%s\n\n' "$contents" "$SRC_TARGETS" > "$scriptdir/Makefile"
1637 # Generate the individual test targets.
1638 if [ "$bc" -ne 0 ]; then
1639 gen_std_tests bc "$extra_math" "$time_tests" $bc_test_exec
1640 gen_script_tests bc "$extra_math" "$generate_tests" "$time_tests" $bc_test_exec
1641 gen_err_tests bc $bc_test_exec
1644 if [ "$dc" -ne 0 ]; then
1645 gen_std_tests dc "$extra_math" "$time_tests" $dc_test_exec
1646 gen_script_tests dc "$extra_math" "$generate_tests" "$time_tests" $dc_test_exec
1647 gen_err_tests dc $dc_test_exec
1652 # Copy the correct manuals to the expected places.
1653 cp -f manuals/bc/$manpage_args.1.md manuals/bc.1.md
1654 cp -f manuals/bc/$manpage_args.1 manuals/bc.1
1655 cp -f manuals/dc/$manpage_args.1.md manuals/dc.1.md
1656 cp -f manuals/dc/$manpage_args.1 manuals/dc.1
1658 make clean > /dev/null