1#! /bin/sh
2#
3# SPDX-License-Identifier: BSD-2-Clause
4#
5# Copyright (c) 2018-2024 Gavin D. Howard and contributors.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are met:
9#
10# * Redistributions of source code must retain the above copyright notice, this
11#   list of conditions and the following disclaimer.
12#
13# * Redistributions in binary form must reproduce the above copyright notice,
14#   this list of conditions and the following disclaimer in the documentation
15#   and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28#
29
30script="$0"
31scriptdir=$(dirname "$script")
32script=$(basename "$script")
33
34builddir=$(pwd)
35
36. "$scriptdir/scripts/functions.sh"
37
38# Simply prints the help message and quits based on the argument.
39# @param msg  The help message to print.
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] [-CeEfgGHilmMNPrtTvz] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\\\n' "$script"
56	printf '       [-s SETTING] [-S SETTING] [-p TYPE]\n'
57	printf '    %s \\\n' "$script"
58	printf '       [--library|--bc-only --disable-dc|--dc-only --disable-bc|--coverage]  \\\n'
59	printf '       [--force --debug --disable-extra-math --disable-generated-tests]      \\\n'
60	printf '       [--disable-history --disable-man-pages --disable-nls --disable-strip] \\\n'
61	printf '       [--enable-editline] [--enable-readline] [--enable-internal-history]   \\\n'
62	printf '       [--disable-problematic-tests] [--install-all-locales]                 \\\n'
63	printf '       [--opt=OPT_LEVEL] [--karatsuba-len=KARATSUBA_LEN]                     \\\n'
64	printf '       [--set-default-on=SETTING] [--set-default-off=SETTING]                \\\n'
65	printf '       [--predefined-build-type=TYPE]                                        \\\n'
66	printf '       [--prefix=PREFIX] [--bindir=BINDIR] [--datarootdir=DATAROOTDIR]       \\\n'
67	printf '       [--datadir=DATADIR] [--mandir=MANDIR] [--man1dir=MAN1DIR]             \\\n'
68	printf '       [--man3dir=MAN3DIR]\n'
69
70	if [ "$_usage_val" -ne 0 ]; then
71		exit "$_usage_val"
72	fi
73
74	printf '\n'
75	printf '    -a, --library\n'
76	printf '        Build the libbcl instead of the programs. This is meant to be used with\n'
77	printf '        Other software like programming languages that want to make use of the\n'
78	printf '        parsing and math capabilities. This option will install headers using\n'
79	printf '        `make install`.\n'
80	printf '    -b, --bc-only\n'
81	printf '        Build bc only. It is an error if "-d", "--dc-only", "-B", or\n'
82	printf '        "--disable-bc" are specified too.\n'
83	printf '    -B, --disable-bc\n'
84	printf '        Disable bc. It is an error if "-b", "--bc-only", "-D", or "--disable-dc"\n'
85	printf '        are specified too.\n'
86	printf '    -c, --coverage\n'
87	printf '        Generate test coverage code. Requires gcov and gcovr.\n'
88	printf '        It is an error if either "-b" ("-D") or "-d" ("-B") is specified.\n'
89	printf '        Requires a compiler that use gcc-compatible coverage options\n'
90	printf '    -C, --disable-clean\n'
91	printf '        Disable the clean that configure.sh does before configure.\n'
92	printf '    -d, --dc-only\n'
93	printf '        Build dc only. It is an error if "-b", "--bc-only", "-D", or\n'
94	printf '        "--disable-dc" are specified too.\n'
95	printf '    -D, --disable-dc\n'
96	printf '        Disable dc. It is an error if "-d", "--dc-only", "-B", or "--disable-bc"\n'
97	printf '        are specified too.\n'
98	printf '    -e, --enable-editline\n'
99	printf '        Enable the use of libedit/editline. This is meant for those users that\n'
100	printf '        want vi-like or Emacs-like behavior in history. This option is ignored\n'
101	printf '        if history is disabled. If the -r or -i options are given with this\n'
102	printf '        option, the last occurrence of all of the three is used.\n'
103	printf '    -E, --disable-extra-math\n'
104	printf '        Disable extra math. This includes: "$" operator (truncate to integer),\n'
105	printf '        "@" operator (set number of decimal places), and r(x, p) (rounding\n'
106	printf '        function). Additionally, this option disables the extra printing\n'
107	printf '        functions in the math library.\n'
108	printf '    -f, --force\n'
109	printf '        Force use of all enabled options, even if they do not work. This\n'
110	printf '        option is to allow the maintainer a way to test that certain options\n'
111	printf '        are not failing invisibly. (Development only.)\n'
112	printf '    -g, --debug\n'
113	printf '        Build in debug mode. Adds the "-g" flag, and if there are no\n'
114	printf '        other CFLAGS, and "-O" was not given, this also adds the "-O0"\n'
115	printf '        flag. If this flag is *not* given, "-DNDEBUG" is added to CPPFLAGS\n'
116	printf '        and a strip flag is added to the link stage.\n'
117	printf '    -G, --disable-generated-tests\n'
118	printf '        Disable generating tests. This is for platforms that do not have a\n'
119	printf '        GNU bc-compatible bc to generate tests.\n'
120	printf '    -h, --help\n'
121	printf '        Print this help message and exit.\n'
122	printf '    -H, --disable-history\n'
123	printf '        Disable history.\n'
124	printf '    -i, --enable-internal-history\n'
125	printf '        Enable the internal history implementation and do not depend on either\n'
126	printf '        editline or readline. This option is ignored if history is disabled.\n'
127	printf '        If this option is given along with -e and -r, the last occurrence of\n'
128	printf '        all of the three is used.\n'
129	printf '    -k KARATSUBA_LEN, --karatsuba-len KARATSUBA_LEN\n'
130	printf '        Set the karatsuba length to KARATSUBA_LEN (default is 32).\n'
131	printf '        It is an error if KARATSUBA_LEN is not a number or is less than 16.\n'
132	printf '    -l, --install-all-locales\n'
133	printf '        Installs all locales, regardless of how many are on the system. This\n'
134	printf '        option is useful for package maintainers who want to make sure that\n'
135	printf '        a package contains all of the locales that end users might need.\n'
136	printf '    -m, --enable-memcheck\n'
137	printf '        Enable memcheck mode, to ensure no memory leaks. For development only.\n'
138	printf '    -M, --disable-man-pages\n'
139	printf '        Disable installing manpages.\n'
140	printf '    -N, --disable-nls\n'
141	printf '        Disable POSIX locale (NLS) support.\n'
142	printf '        ***WARNING***: Locales ignore the prefix because they *must* be\n'
143	printf '        installed at a fixed location to work at all. If you do not want that\n'
144	printf '        to happen, you must disable locales (NLS) completely.\n'
145	printf '    -O OPT_LEVEL, --opt OPT_LEVEL\n'
146	printf '        Set the optimization level. This can also be included in the CFLAGS,\n'
147	printf '        but it is provided, so maintainers can build optimized debug builds.\n'
148	printf '        This is passed through to the compiler, so it must be supported.\n'
149	printf '    -p TYPE, --predefined-build-type=TYPE\n'
150	printf '        Sets a given predefined build type with specific defaults. This is for\n'
151	printf '        easy setting of predefined builds. For example, to get a build that\n'
152	printf '        acts like the GNU bc by default, TYPE should be "GNU" (without the\n'
153	printf '        quotes) This option *must* come before any others that might change the\n'
154	printf '        build options. Currently supported values for TYPE include: "BSD" (for\n'
155	printf '        matching the BSD bc and BSD dc), "GNU" (for matching the GNU bc and\n'
156	printf '        dc), "GDH" (for the preferred build of the author, Gavin D. Howard),\n'
157	printf '        and "DBG" (for the preferred debug build of the author). This will\n'
158	printf '        also automatically enable a release build (except for "DBG").\n'
159	printf '    -P, --disable-problematic-tests\n'
160	printf '        Disables problematic tests. These tests usually include tests that\n'
161	printf '        can cause a SIGKILL because of too much memory usage.\n'
162	printf '    -r, --enable-readline\n'
163	printf '        Enable the use of libreadline/readline. This is meant for those users\n'
164	printf '        that want vi-like or Emacs-like behavior in history. This option is\n'
165	printf '        ignored if history is disabled. If this option is given along with -e\n'
166	printf '        and -i, the last occurrence of all of the three is used.\n'
167	printf '    -s SETTING, --set-default-on SETTING\n'
168	printf '        Set the default named by SETTING to on. See below for possible values\n'
169	printf '        for SETTING. For multiple instances of the -s or -S for the the same\n'
170	printf '        setting, the last one is used.\n'
171	printf '    -S SETTING, --set-default-off SETTING\n'
172	printf '        Set the default named by SETTING to off. See below for possible values\n'
173	printf '        for SETTING. For multiple instances of the -s or -S for the the same\n'
174	printf '        setting, the last one is used.\n'
175	printf '    -t, --enable-test-timing\n'
176	printf '        Enable the timing of tests. This is for development only.\n'
177	printf '    -T, --disable-strip\n'
178	printf '        Disable stripping symbols from the compiled binary or binaries.\n'
179	printf '        Stripping symbols only happens when debug mode is off.\n'
180	printf '    -v, --enable-valgrind\n'
181	printf '        Enable a build appropriate for valgrind. For development only.\n'
182	printf '    -z, --enable-fuzz-mode\n'
183	printf '        Enable fuzzing mode. THIS IS FOR DEVELOPMENT ONLY.\n'
184	printf '    -Z, --enable-ossfuzz-mode\n'
185	printf '        Enable fuzzing mode for OSS-Fuzz. THIS IS FOR DEVELOPMENT ONLY.\n'
186	printf '    --prefix PREFIX\n'
187	printf '        The prefix to install to. Overrides "$PREFIX" if it exists.\n'
188	printf '        If PREFIX is "/usr", install path will be "/usr/bin".\n'
189	printf '        Default is "/usr/local".\n'
190	printf '        ***WARNING***: Locales ignore the prefix because they *must* be\n'
191	printf '        installed at a fixed location to work at all. If you do not want that to\n'
192	printf '        happen, you must disable locales (NLS) completely.\n'
193	printf '    --bindir BINDIR\n'
194	printf '        The directory to install binaries in. Overrides "$BINDIR" if it exists.\n'
195	printf '        Default is "$PREFIX/bin".\n'
196	printf '    --includedir INCLUDEDIR\n'
197	printf '        The directory to install headers in. Overrides "$INCLUDEDIR" if it\n'
198	printf '        exists. Default is "$PREFIX/include".\n'
199	printf '    --libdir LIBDIR\n'
200	printf '        The directory to install libraries in. Overrides "$LIBDIR" if it exists.\n'
201	printf '        Default is "$PREFIX/lib".\n'
202	printf '    --datarootdir DATAROOTDIR\n'
203	printf '        The root location for data files. Overrides "$DATAROOTDIR" if it exists.\n'
204	printf '        Default is "$PREFIX/share".\n'
205	printf '    --datadir DATADIR\n'
206	printf '        The location for data files. Overrides "$DATADIR" if it exists.\n'
207	printf '        Default is "$DATAROOTDIR".\n'
208	printf '    --mandir MANDIR\n'
209	printf '        The location to install manpages to. Overrides "$MANDIR" if it exists.\n'
210	printf '        Default is "$DATADIR/man".\n'
211	printf '    --man1dir MAN1DIR\n'
212	printf '        The location to install Section 1 manpages to. Overrides "$MAN1DIR" if\n'
213	printf '        it exists. Default is "$MANDIR/man1".\n'
214	printf '    --man3dir MAN3DIR\n'
215	printf '        The location to install Section 3 manpages to. Overrides "$MAN3DIR" if\n'
216	printf '        it exists. Default is "$MANDIR/man3".\n'
217	printf '\n'
218	printf 'In addition, the following environment variables are used:\n'
219	printf '\n'
220	printf '    CC           C compiler. Must be compatible with POSIX c99. If there is a\n'
221	printf '                 space in the basename of the compiler, the items after the\n'
222	printf '                 first space are assumed to be compiler flags, and in that case,\n'
223	printf '                 the flags are automatically moved into CFLAGS. Default is\n'
224	printf '                 "c99".\n'
225	printf '    HOSTCC       Host C compiler. Must be compatible with POSIX c99. If there is\n'
226	printf '                 a space in the basename of the compiler, the items after the\n'
227	printf '                 first space are assumed to be compiler flags, and in the case,\n'
228	printf '                 the flags are automatically moved into HOSTCFLAGS. Default is\n'
229	printf '                 "$CC".\n'
230	printf '    HOST_CC      Same as HOSTCC. If HOSTCC also exists, it is used.\n'
231	printf '    CFLAGS       C compiler flags.\n'
232	printf '    HOSTCFLAGS   CFLAGS for HOSTCC. Default is "$CFLAGS".\n'
233	printf '    HOST_CFLAGS  Same as HOST_CFLAGS. If HOST_CFLAGS also exists, it is used.\n'
234	printf '    CPPFLAGS     C preprocessor flags. Default is "".\n'
235	printf '    LDFLAGS      Linker flags. Default is "".\n'
236	printf '    PREFIX       The prefix to install to. Default is "/usr/local".\n'
237	printf '                 If PREFIX is "/usr", install path will be "/usr/bin".\n'
238	printf '                 ***WARNING***: Locales ignore the prefix because they *must* be\n'
239	printf '                 installed at a fixed location to work at all. If you do not\n'
240	printf '                 want that to happen, you must disable locales (NLS) completely.\n'
241	printf '    BINDIR       The directory to install binaries in. Default is "$PREFIX/bin".\n'
242	printf '    INCLUDEDIR   The directory to install header files in. Default is\n'
243	printf '                 "$PREFIX/include".\n'
244	printf '    LIBDIR       The directory to install libraries in. Default is\n'
245	printf '                 "$PREFIX/lib".\n'
246	printf '    DATAROOTDIR  The root location for data files. Default is "$PREFIX/share".\n'
247	printf '    DATADIR      The location for data files. Default is "$DATAROOTDIR".\n'
248	printf '    MANDIR       The location to install manpages to. Default is "$DATADIR/man".\n'
249	printf '    MAN1DIR      The location to install Section 1 manpages to. Default is\n'
250	printf '                 "$MANDIR/man1".\n'
251	printf '    MAN3DIR      The location to install Section 3 manpages to. Default is\n'
252	printf '                 "$MANDIR/man3".\n'
253	printf '    NLSPATH      The location to install locale catalogs to. Must be an absolute\n'
254	printf '                 path (or contain one). This is treated the same as the POSIX\n'
255	printf '                 definition of $NLSPATH (see POSIX environment variables for\n'
256	printf '                 more information). Default is "/usr/share/locale/%%L/%%N".\n'
257	printf '    PC_PATH      The location to install pkg-config files to. Must be an\n'
258	printf '                 path or contain one. Default is the first path given by the\n'
259	printf '                 output of `pkg-config --variable=pc_path pkg-config`.\n'
260	printf '    EXECSUFFIX   The suffix to append to the executable names, used to not\n'
261	printf '                 interfere with other installed bc executables. Default is "".\n'
262	printf '    EXECPREFIX   The prefix to append to the executable names, used to not\n'
263	printf '                 interfere with other installed bc executables. Default is "".\n'
264	printf '    DESTDIR      For package creation. Default is "". If it is empty when\n'
265	printf '                 `%s` is run, it can also be passed to `make install`\n' "$script"
266	printf '                 later as an environment variable. If both are specified,\n'
267	printf '                 the one given to `%s` takes precedence.\n' "$script"
268	printf '    LONG_BIT     The number of bits in a C `long` type. This is mostly for the\n'
269	printf '                 embedded space since this `bc` uses `long`s internally for\n'
270	printf '                 overflow checking. In C99, a `long` is required to be 32 bits.\n'
271	printf '                 For most normal desktop systems, setting this is unnecessary,\n'
272	printf '                 except that 32-bit platforms with 64-bit longs may want to set\n'
273	printf '                 it to `32`. Default is the default of `LONG_BIT` for the target\n'
274	printf '                 platform. Minimum allowed is `32`. It is a build time error if\n'
275	printf '                 the specified value of `LONG_BIT` is greater than the default\n'
276	printf '                 value of `LONG_BIT` for the target platform.\n'
277	printf '    GEN_HOST     Whether to use `gen/strgen.c`, instead of `gen/strgen.sh`, to\n'
278	printf '                 produce the C files that contain the help texts as well as the\n'
279	printf '                 math libraries. By default, `gen/strgen.c` is used, compiled by\n'
280	printf '                 "$HOSTCC" and run on the host machine. Using `gen/strgen.sh`\n'
281	printf '                 removes the need to compile and run an executable on the host\n'
282	printf '                 machine since `gen/strgen.sh` is a POSIX shell script. However,\n'
283	printf '                 `gen/lib2.bc` is over 4095 characters, the max supported length\n'
284	printf '                 of a string literal in C99, and `gen/strgen.sh` generates a\n'
285	printf '                 string literal instead of an array, as `gen/strgen.c` does. For\n'
286	printf '                 most production-ready compilers, this limit probably is not\n'
287	printf '                 enforced, but it could be. Both options are still available for\n'
288	printf '                 this reason. If you are sure your compiler does not have the\n'
289	printf '                 limit and do not want to compile and run a binary on the host\n'
290	printf '                 machine, set this variable to "0". Any other value, or a\n'
291	printf '                 non-existent value, will cause the build system to compile and\n'
292	printf '                 run `gen/strgen.c`. Default is "".\n'
293	printf '    GEN_EMU      Emulator to run string generator code under (leave empty if not\n'
294	printf '                 necessary). This is not necessary when using `gen/strgen.sh`.\n'
295	printf '                 Default is "".\n'
296	printf '\n'
297	printf 'WARNING: even though `configure.sh` supports both option types, short and\n'
298	printf 'long, it does not support handling both at the same time. Use only one type.\n'
299	printf '\n'
300	printf 'Settings\n'
301	printf '========\n'
302	printf '\n'
303	printf 'bc and dc have some settings that, while they cannot be removed by build time\n'
304	printf 'options, can have their defaults changed at build time by packagers. Users are\n'
305	printf 'also able to change each setting with environment variables.\n'
306	printf '\n'
307	printf 'The following is a table of settings, along with their default values and the\n'
308	printf 'environment variables users can use to change them. (For the defaults, non-zero\n'
309	printf 'means on, and zero means off.)\n'
310	printf '\n'
311	printf '| Setting         | Description          | Default      | Env Variable         |\n'
312	printf '| =============== | ==================== | ============ | ==================== |\n'
313	printf '| bc.banner       | Whether to display   |            0 | BC_BANNER            |\n'
314	printf '|                 | the bc version       |              |                      |\n'
315	printf '|                 | banner when in       |              |                      |\n'
316	printf '|                 | interactive mode.    |              |                      |\n'
317	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
318	printf '| bc.sigint_reset | Whether SIGINT will  |            1 | BC_SIGINT_RESET      |\n'
319	printf '|                 | reset bc, instead of |              |                      |\n'
320	printf '|                 | exiting, when in     |              |                      |\n'
321	printf '|                 | interactive mode.    |              |                      |\n'
322	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
323	printf '| dc.sigint_reset | Whether SIGINT will  |            1 | DC_SIGINT_RESET      |\n'
324	printf '|                 | reset dc, instead of |              |                      |\n'
325	printf '|                 | exiting, when in     |              |                      |\n'
326	printf '|                 | interactive mode.    |              |                      |\n'
327	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
328	printf '| bc.tty_mode     | Whether TTY mode for |            1 | BC_TTY_MODE          |\n'
329	printf '|                 | bc should be on when |              |                      |\n'
330	printf '|                 | available.           |              |                      |\n'
331	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
332	printf '| dc.tty_mode     | Whether TTY mode for |            0 | BC_TTY_MODE          |\n'
333	printf '|                 | dc should be on when |              |                      |\n'
334	printf '|                 | available.           |              |                      |\n'
335	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
336	printf '| bc.prompt       | Whether the prompt   | $BC_TTY_MODE | BC_PROMPT            |\n'
337	printf '|                 | for bc should be on  |              |                      |\n'
338	printf '|                 | in tty mode.         |              |                      |\n'
339	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
340	printf '| dc.prompt       | Whether the prompt   | $DC_TTY_MODE | DC_PROMPT            |\n'
341	printf '|                 | for dc should be on  |              |                      |\n'
342	printf '|                 | in tty mode.         |              |                      |\n'
343	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
344	printf '| bc.expr_exit    | Whether to exit bc   |            1 | BC_EXPR_EXIT         |\n'
345	printf '|                 | if an expression or  |              |                      |\n'
346	printf '|                 | expression file is   |              |                      |\n'
347	printf '|                 | given with the -e or |              |                      |\n'
348	printf '|                 | -f options.          |              |                      |\n'
349	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
350	printf '| dc.expr_exit    | Whether to exit dc   |            1 | DC_EXPR_EXIT         |\n'
351	printf '|                 | if an expression or  |              |                      |\n'
352	printf '|                 | expression file is   |              |                      |\n'
353	printf '|                 | given with the -e or |              |                      |\n'
354	printf '|                 | -f options.          |              |                      |\n'
355	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
356	printf '| bc.digit_clamp  | Whether to have bc   |            0 | BC_DIGIT_CLAMP       |\n'
357	printf '|                 | clamp digits that    |              |                      |\n'
358	printf '|                 | are greater than or  |              |                      |\n'
359	printf '|                 | equal to the current |              |                      |\n'
360	printf '|                 | ibase when parsing   |              |                      |\n'
361	printf '|                 | numbers.             |              |                      |\n'
362	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
363	printf '| dc.digit_clamp  | Whether to have dc   |            0 | DC_DIGIT_CLAMP       |\n'
364	printf '|                 | clamp digits that    |              |                      |\n'
365	printf '|                 | are greater than or  |              |                      |\n'
366	printf '|                 | equal to the current |              |                      |\n'
367	printf '|                 | ibase when parsing   |              |                      |\n'
368	printf '|                 | numbers.             |              |                      |\n'
369	printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
370	printf '\n'
371	printf 'These settings are not meant to be changed on a whim. They are meant to ensure\n'
372	printf 'that this bc and dc will conform to the expectations of the user on each\n'
373	printf 'platform.\n'
374
375	exit "$_usage_val"
376}
377
378# Replaces a file extension in a filename. This is used mostly to turn filenames
379# like `src/num.c` into `src/num.o`. In other words, it helps to link targets to
380# the files they depend on.
381#
382# @param file  The filename.
383# @param ext1  The extension to replace.
384# @param ext2  The new extension.
385replace_ext() {
386
387	if [ "$#" -ne 3 ]; then
388		err_exit "Invalid number of args to $0"
389	fi
390
391	_replace_ext_file="$1"
392	_replace_ext_ext1="$2"
393	_replace_ext_ext2="$3"
394
395	_replace_ext_result="${_replace_ext_file%.$_replace_ext_ext1}.$_replace_ext_ext2"
396
397	printf '%s\n' "$_replace_ext_result"
398}
399
400# Replaces a file extension in every filename given in a list. The list is just
401# a space-separated list of words, so filenames are expected to *not* have
402# spaces in them. See the documentation for `replace_ext()`.
403#
404# @param files  The list of space-separated filenames to replace extensions for.
405# @param ext1   The extension to replace.
406# @param ext2   The new extension.
407replace_exts() {
408
409	if [ "$#" -ne 3 ]; then
410		err_exit "Invalid number of args to $0"
411	fi
412
413	_replace_exts_files="$1"
414	_replace_exts_ext1="$2"
415	_replace_exts_ext2="$3"
416
417	for _replace_exts_file in $_replace_exts_files; do
418		_replace_exts_new_name=$(replace_ext "$_replace_exts_file" "$_replace_exts_ext1" "$_replace_exts_ext2")
419		_replace_exts_result="$_replace_exts_result $_replace_exts_new_name"
420	done
421
422	printf '%s\n' "$_replace_exts_result"
423}
424
425# Finds a placeholder in @a str and replaces it. This is the workhorse of
426# configure.sh. It's what replaces placeholders in Makefile.in with the data
427# needed for the chosen build. Below, you will see a lot of calls to this
428# function.
429#
430# Note that needle can never contain an exclamation point. For more information,
431# see substring_replace() in scripts/functions.sh.
432#
433# @param str          The string to find and replace placeholders in.
434# @param needle       The placeholder name.
435# @param replacement  The string to use to replace the placeholder.
436replace() {
437
438	if [ "$#" -ne 3 ]; then
439		err_exit "Invalid number of args to $0"
440	fi
441
442	_replace_str="$1"
443	_replace_needle="$2"
444	_replace_replacement="$3"
445
446	substring_replace "$_replace_str" "%%$_replace_needle%%" "$_replace_replacement"
447}
448
449# This function finds all the source files that need to be built. If there is
450# only one argument and it is empty, then all source files are built. Otherwise,
451# the arguments are all assumed to be source files that should *not* be built.
452find_src_files() {
453
454	_find_src_files_args=""
455
456	if [ "$#" -ge 1 ] && [ "$1" != "" ]; then
457
458		while [ "$#" -ge 1 ]; do
459			_find_src_files_a="${1## }"
460			shift
461			_find_src_files_args=$(printf '%s\n%s/src/%s\n' "$_find_src_files_args" "$scriptdir" "${_find_src_files_a}")
462		done
463
464	fi
465
466	_find_src_files_files=$(find "$scriptdir/src" -depth -name "*.c" -print | LC_ALL=C sort)
467
468	_find_src_files_result=""
469
470	for _find_src_files_f in $_find_src_files_files; do
471
472		# If this is true, the file is part of args, and therefore, unneeded.
473		if [ "${_find_src_files_args##*$_find_src_files_f}" != "${_find_src_files_args}" ]; then
474			continue
475		fi
476
477		_find_src_files_result=$(printf '%s\n%s\n' "$_find_src_files_result" "$_find_src_files_f")
478
479	done
480
481	printf '%s\n' "$_find_src_files_result"
482}
483
484# This function generates a list of files to go into the Makefile. It generates
485# the list of object files, as well as the list of test coverage files.
486#
487# @param contents  The contents of the Makefile template to put the list of
488#                  files into.
489gen_file_list() {
490
491	if [ "$#" -lt 1 ]; then
492		err_exit "Invalid number of args to $0"
493	fi
494
495	_gen_file_list_contents="$1"
496	shift
497
498	if [ "$#" -ge 1 ]; then
499		_gen_file_list_unneeded="$@"
500	else
501		_gen_file_list_unneeded=""
502	fi
503
504	_gen_file_list_needle_src="SRC"
505	_gen_file_list_needle_obj="OBJ"
506	_gen_file_list_needle_gcda="GCDA"
507	_gen_file_list_needle_gcno="GCNO"
508
509	_gen_file_list_replacement=$(find_src_files $_gen_file_list_unneeded | tr '\n' ' ')
510	_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
511		"$_gen_file_list_needle_src" "$_gen_file_list_replacement")
512
513	_gen_file_list_cbases=""
514
515	for _gen_file_list_f in $_gen_file_list_replacement; do
516		_gen_file_list_b=$(basename "$_gen_file_list_f")
517		_gen_file_list_cbases="$_gen_file_list_cbases src/$_gen_file_list_b"
518	done
519
520	_gen_file_list_replacement=$(replace_exts "$_gen_file_list_cbases" "c" "o")
521	_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
522		"$_gen_file_list_needle_obj" "$_gen_file_list_replacement")
523
524	_gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "o" "gcda")
525	_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
526		"$_gen_file_list_needle_gcda" "$_gen_file_list_replacement")
527
528	_gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "gcda" "gcno")
529	_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
530		"$_gen_file_list_needle_gcno" "$_gen_file_list_replacement")
531
532	printf '%s\n' "$_gen_file_list_contents"
533}
534
535# Generates the proper test targets for each test to have its own target. This
536# allows `make test` to run in parallel.
537#
538# @param name        Which calculator to generate tests for.
539# @param extra_math  An integer that, if non-zero, activates extra math tests.
540# @param time_tests  An integer that, if non-zero, tells the test suite to time
541#                    the execution of each test.
542gen_std_tests() {
543
544	_gen_std_tests_name="$1"
545	shift
546
547	_gen_std_tests_extra_math="$1"
548	shift
549
550	_gen_std_tests_time_tests="$1"
551	shift
552
553	_gen_std_tests_extra_required=$(cat "$scriptdir/tests/extra_required.txt")
554
555	for _gen_std_tests_t in $(cat "$scriptdir/tests/$_gen_std_tests_name/all.txt"); do
556
557		if [ "$_gen_std_tests_extra_math" -eq 0 ]; then
558
559			if [ -z "${_gen_std_tests_extra_required##*$_gen_std_tests_t*}" ]; then
560				printf 'test_%s_%s:\n\t@printf "Skipping %s %s\\n"\n\n' \
561					"$_gen_std_tests_name" "$_gen_std_tests_t" "$_gen_std_tests_name" \
562					"$_gen_std_tests_t" >> "Makefile"
563				continue
564			fi
565
566		fi
567
568		printf 'test_%s_%s:\n\t@export BC_TEST_OUTPUT_DIR="%s/tests"; sh $(TESTSDIR)/test.sh %s %s %s %s %s\n\n' \
569			"$_gen_std_tests_name" "$_gen_std_tests_t" "$builddir" "$_gen_std_tests_name" \
570			"$_gen_std_tests_t" "$generate_tests" "$time_tests" \
571			"$*" >> "Makefile"
572
573	done
574}
575
576# Generates a list of test targets that will be used as prerequisites for other
577# targets.
578#
579# @param name  The name of the calculator to generate test targets for.
580gen_std_test_targets() {
581
582	_gen_std_test_targets_name="$1"
583	shift
584
585	_gen_std_test_targets_tests=$(cat "$scriptdir/tests/${_gen_std_test_targets_name}/all.txt")
586
587	for _gen_std_test_targets_t in $_gen_std_test_targets_tests; do
588		printf ' test_%s_%s' "$_gen_std_test_targets_name" "$_gen_std_test_targets_t"
589	done
590
591	printf '\n'
592}
593
594# Generates the proper test targets for each error test to have its own target.
595# This allows `make test_bc_errors` and `make test_dc_errors` to run in
596# parallel.
597#
598# @param name  Which calculator to generate tests for.
599gen_err_tests() {
600
601	_gen_err_tests_name="$1"
602	shift
603
604	_gen_err_tests_fs=$(ls "$scriptdir/tests/$_gen_err_tests_name/errors/")
605
606	for _gen_err_tests_t in $_gen_err_tests_fs; do
607
608		printf 'test_%s_error_%s:\n\t@export BC_TEST_OUTPUT_DIR="%s/tests"; sh $(TESTSDIR)/error.sh %s %s %s %s\n\n' \
609			"$_gen_err_tests_name" "$_gen_err_tests_t" "$builddir" "$_gen_err_tests_name" \
610			"$_gen_err_tests_t" "$problematic_tests" "$*" >> "Makefile"
611
612	done
613
614}
615
616# Generates a list of error test targets that will be used as prerequisites for
617# other targets.
618#
619# @param name  The name of the calculator to generate test targets for.
620gen_err_test_targets() {
621
622	_gen_err_test_targets_name="$1"
623	shift
624
625	_gen_err_test_targets_tests=$(ls "$scriptdir/tests/$_gen_err_test_targets_name/errors/")
626
627	for _gen_err_test_targets_t in $_gen_err_test_targets_tests; do
628		printf ' test_%s_error_%s' "$_gen_err_test_targets_name" "$_gen_err_test_targets_t"
629	done
630
631	printf '\n'
632}
633
634# Generates the proper script test targets for each script test to have its own
635# target. This allows `make test` to run in parallel.
636#
637# @param name        Which calculator to generate tests for.
638# @param extra_math  An integer that, if non-zero, activates extra math tests.
639# @param generate    An integer that, if non-zero, activates generated tests.
640# @param time_tests  An integer that, if non-zero, tells the test suite to time
641#                    the execution of each test.
642gen_script_tests() {
643
644	_gen_script_tests_name="$1"
645	shift
646
647	_gen_script_tests_extra_math="$1"
648	shift
649
650	_gen_script_tests_generate="$1"
651	shift
652
653	_gen_script_tests_time="$1"
654	shift
655
656	_gen_script_tests_tests=$(cat "$scriptdir/tests/$_gen_script_tests_name/scripts/all.txt")
657
658	for _gen_script_tests_f in $_gen_script_tests_tests; do
659
660		_gen_script_tests_b=$(basename "$_gen_script_tests_f" ".${_gen_script_tests_name}")
661
662		printf 'test_%s_script_%s:\n\t@export BC_TEST_OUTPUT_DIR="%s/tests"; sh $(TESTSDIR)/script.sh %s %s %s 1 %s %s %s\n\n' \
663			"$_gen_script_tests_name" "$_gen_script_tests_b" "$builddir" "$_gen_script_tests_name" \
664			"$_gen_script_tests_f" "$_gen_script_tests_extra_math" "$_gen_script_tests_generate" \
665			"$_gen_script_tests_time" "$*" >> "Makefile"
666	done
667}
668
669set_default() {
670
671	_set_default_on="$1"
672	shift
673
674	_set_default_name="$1"
675	shift
676
677	# The reason that the variables that are being set do not have the same
678	# non-collision avoidance that the other variables do is that we *do* want
679	# the settings of these variables to leak out of the function. They adjust
680	# the settings outside of the function.
681	case "$_set_default_name" in
682
683		bc.banner) bc_default_banner="$_set_default_on" ;;
684		bc.sigint_reset) bc_default_sigint_reset="$_set_default_on" ;;
685		dc.sigint_reset) dc_default_sigint_reset="$_set_default_on" ;;
686		bc.tty_mode) bc_default_tty_mode="$_set_default_on" ;;
687		dc.tty_mode) dc_default_tty_mode="$_set_default_on" ;;
688		bc.prompt) bc_default_prompt="$_set_default_on" ;;
689		dc.prompt) dc_default_prompt="$_set_default_on" ;;
690		bc.expr_exit) bc_default_expr_exit="$_set_default_on";;
691		dc.expr_exit) dc_default_expr_exit="$_set_default_on";;
692		bc.digit_clamp) bc_default_digit_clamp="$_set_default_on";;
693		dc.digit_clamp) dc_default_digit_clamp="$_set_default_on";;
694		?) usage "Invalid setting: $_set_default_name" ;;
695
696	esac
697}
698
699predefined_build() {
700
701	_predefined_build_type="$1"
702	shift
703
704	# The reason that the variables that are being set do not have the same
705	# non-collision avoidance that the other variables do is that we *do* want
706	# the settings of these variables to leak out of the function. They adjust
707	# the settings outside of the function.
708	case "$_predefined_build_type" in
709
710		BSD)
711			bc_only=0
712			dc_only=0
713			coverage=0
714			debug=0
715			optimization="3"
716			hist=1
717			hist_impl="editline"
718			extra_math=1
719			generate_tests=$generate_tests
720			install_manpages=0
721			nls=1
722			force=0
723			strip_bin=1
724			all_locales=0
725			library=0
726			fuzz=0
727			ossfuzz=0
728			time_tests=0
729			vg=0
730			memcheck=0
731			clean=1
732			bc_default_banner=0
733			bc_default_sigint_reset=1
734			dc_default_sigint_reset=1
735			bc_default_tty_mode=1
736			dc_default_tty_mode=0
737			bc_default_prompt=""
738			dc_default_prompt=""
739			bc_default_expr_exit=1
740			dc_default_expr_exit=1
741			bc_default_digit_clamp=0
742			dc_default_digit_clamp=0;;
743
744		GNU)
745			bc_only=0
746			dc_only=0
747			coverage=0
748			debug=0
749			optimization="3"
750			hist=1
751			hist_impl="internal"
752			extra_math=1
753			generate_tests=$generate_tests
754			install_manpages=1
755			nls=1
756			force=0
757			strip_bin=1
758			all_locales=0
759			library=0
760			fuzz=0
761			ossfuzz=0
762			time_tests=0
763			vg=0
764			memcheck=0
765			clean=1
766			bc_default_banner=1
767			bc_default_sigint_reset=1
768			dc_default_sigint_reset=0
769			bc_default_tty_mode=1
770			dc_default_tty_mode=0
771			bc_default_prompt=""
772			dc_default_prompt=""
773			bc_default_expr_exit=1
774			dc_default_expr_exit=1
775			bc_default_digit_clamp=1
776			dc_default_digit_clamp=0;;
777
778		GDH)
779			CFLAGS="-Weverything -Wno-padded -Wno-unsafe-buffer-usage -Wno-poison-system-directories"
780			CFLAGS="$CFLAGS -Wno-switch-default -Werror -pedantic -std=c11"
781			bc_only=0
782			dc_only=0
783			coverage=0
784			debug=0
785			optimization="3"
786			hist=1
787			hist_impl="internal"
788			extra_math=1
789			generate_tests=1
790			install_manpages=1
791			nls=0
792			force=0
793			strip_bin=1
794			all_locales=0
795			library=0
796			fuzz=0
797			ossfuzz=0
798			time_tests=0
799			vg=0
800			memcheck=0
801			clean=1
802			bc_default_banner=1
803			bc_default_sigint_reset=1
804			dc_default_sigint_reset=1
805			bc_default_tty_mode=1
806			dc_default_tty_mode=1
807			bc_default_prompt=""
808			dc_default_prompt=""
809			bc_default_expr_exit=0
810			dc_default_expr_exit=0
811			bc_default_digit_clamp=1
812			dc_default_digit_clamp=1;;
813
814		DBG)
815			CFLAGS="-Weverything -Wno-padded -Wno-unsafe-buffer-usage -Wno-poison-system-directories"
816			CFLAGS="$CFLAGS -Wno-switch-default -Werror -pedantic -std=c11"
817			bc_only=0
818			dc_only=0
819			coverage=0
820			debug=1
821			optimization="0"
822			hist=1
823			hist_impl="internal"
824			extra_math=1
825			generate_tests=1
826			install_manpages=1
827			nls=1
828			force=0
829			strip_bin=1
830			all_locales=0
831			library=0
832			fuzz=0
833			ossfuzz=0
834			time_tests=0
835			vg=0
836			memcheck=1
837			clean=1
838			bc_default_banner=1
839			bc_default_sigint_reset=1
840			dc_default_sigint_reset=1
841			bc_default_tty_mode=1
842			dc_default_tty_mode=1
843			bc_default_prompt=""
844			dc_default_prompt=""
845			bc_default_expr_exit=0
846			dc_default_expr_exit=0
847			bc_default_digit_clamp=1
848			dc_default_digit_clamp=1;;
849
850		?|'') usage "Invalid user build: \"$_predefined_build_type\". Accepted types are BSD, GNU, GDH, DBG.";;
851
852	esac
853}
854
855# Generates a list of script test targets that will be used as prerequisites for
856# other targets.
857#
858# @param name  The name of the calculator to generate script test targets for.
859gen_script_test_targets() {
860
861	_gen_script_test_targets_name="$1"
862	shift
863
864	_gen_script_test_targets_tests=$(cat "$scriptdir/tests/$_gen_script_test_targets_name/scripts/all.txt")
865
866	for _gen_script_test_targets_f in $_gen_script_test_targets_tests; do
867		_gen_script_test_targets_b=$(basename "$_gen_script_test_targets_f" \
868			".$_gen_script_test_targets_name")
869		printf ' test_%s_script_%s' "$_gen_script_test_targets_name" \
870			"$_gen_script_test_targets_b"
871	done
872
873	printf '\n'
874}
875
876# This is a list of defaults, but it is also the list of possible options for
877# users to change.
878#
879# The development options are: force (force options even if they fail), valgrind
880# (build in a way suitable for valgrind testing), memcheck (same as valgrind),
881# and fuzzing (build in a way suitable for fuzzing).
882bc_only=0
883dc_only=0
884coverage=0
885karatsuba_len=32
886debug=0
887hist=1
888hist_impl="internal"
889extra_math=1
890optimization=""
891generate_tests=1
892install_manpages=1
893nls=1
894force=0
895strip_bin=1
896all_locales=0
897library=0
898fuzz=0
899ossfuzz=0
900time_tests=0
901vg=0
902memcheck=0
903clean=1
904problematic_tests=1
905
906# The empty strings are because they depend on TTY mode. If they are directly
907# set, though, they will be integers. We test for empty strings later.
908bc_default_banner=0
909bc_default_sigint_reset=1
910dc_default_sigint_reset=1
911bc_default_tty_mode=1
912dc_default_tty_mode=0
913bc_default_prompt=""
914dc_default_prompt=""
915bc_default_expr_exit=1
916dc_default_expr_exit=1
917bc_default_digit_clamp=0
918dc_default_digit_clamp=0
919
920# getopts is a POSIX utility, but it cannot handle long options. Thus, the
921# handling of long options is done by hand, and that's the reason that short and
922# long options cannot be mixed.
923while getopts "abBcdDeEfgGhHik:lMmNO:p:PrS:s:tTvzZ-" opt; do
924
925	case "$opt" in
926		a) library=1 ;;
927		b) bc_only=1 ;;
928		B) dc_only=1 ;;
929		c) coverage=1 ;;
930		C) clean=0 ;;
931		d) dc_only=1 ;;
932		D) bc_only=1 ;;
933		e) hist_impl="editline" ;;
934		E) extra_math=0 ;;
935		f) force=1 ;;
936		g) debug=1 ;;
937		G) generate_tests=0 ;;
938		h) usage ;;
939		H) hist=0 ;;
940		i) hist_impl="internal" ;;
941		k) karatsuba_len="$OPTARG" ;;
942		l) all_locales=1 ;;
943		m) memcheck=1 ;;
944		M) install_manpages=0 ;;
945		N) nls=0 ;;
946		O) optimization="$OPTARG" ;;
947		p) predefined_build "$OPTARG" ;;
948		P) problematic_tests=0 ;;
949		r) hist_impl="readline" ;;
950		S) set_default 0 "$OPTARG" ;;
951		s) set_default 1 "$OPTARG" ;;
952		t) time_tests=1 ;;
953		T) strip_bin=0 ;;
954		v) vg=1 ;;
955		z) fuzz=1 ;;
956		Z) ossfuzz=1 ;;
957		-)
958			arg="$1"
959			arg="${arg#--}"
960			LONG_OPTARG="${arg#*=}"
961			case $arg in
962				help) usage ;;
963				library) library=1 ;;
964				bc-only) bc_only=1 ;;
965				dc-only) dc_only=1 ;;
966				coverage) coverage=1 ;;
967				debug) debug=1 ;;
968				force) force=1 ;;
969				prefix=?*) PREFIX="$LONG_OPTARG" ;;
970				prefix)
971					if [ "$#" -lt 2 ]; then
972						usage "No argument given for '--$arg' option"
973					fi
974					PREFIX="$2"
975					shift ;;
976				bindir=?*) BINDIR="$LONG_OPTARG" ;;
977				bindir)
978					if [ "$#" -lt 2 ]; then
979						usage "No argument given for '--$arg' option"
980					fi
981					BINDIR="$2"
982					shift ;;
983				includedir=?*) INCLUDEDIR="$LONG_OPTARG" ;;
984				includedir)
985					if [ "$#" -lt 2 ]; then
986						usage "No argument given for '--$arg' option"
987					fi
988					INCLUDEDIR="$2"
989					shift ;;
990				libdir=?*) LIBDIR="$LONG_OPTARG" ;;
991				libdir)
992					if [ "$#" -lt 2 ]; then
993						usage "No argument given for '--$arg' option"
994					fi
995					LIBDIR="$2"
996					shift ;;
997				datarootdir=?*) DATAROOTDIR="$LONG_OPTARG" ;;
998				datarootdir)
999					if [ "$#" -lt 2 ]; then
1000						usage "No argument given for '--$arg' option"
1001					fi
1002					DATAROOTDIR="$2"
1003					shift ;;
1004				datadir=?*) DATADIR="$LONG_OPTARG" ;;
1005				datadir)
1006					if [ "$#" -lt 2 ]; then
1007						usage "No argument given for '--$arg' option"
1008					fi
1009					DATADIR="$2"
1010					shift ;;
1011				mandir=?*) MANDIR="$LONG_OPTARG" ;;
1012				mandir)
1013					if [ "$#" -lt 2 ]; then
1014						usage "No argument given for '--$arg' option"
1015					fi
1016					MANDIR="$2"
1017					shift ;;
1018				man1dir=?*) MAN1DIR="$LONG_OPTARG" ;;
1019				man1dir)
1020					if [ "$#" -lt 2 ]; then
1021						usage "No argument given for '--$arg' option"
1022					fi
1023					MAN1DIR="$2"
1024					shift ;;
1025				man3dir=?*) MAN3DIR="$LONG_OPTARG" ;;
1026				man3dir)
1027					if [ "$#" -lt 2 ]; then
1028						usage "No argument given for '--$arg' option"
1029					fi
1030					MAN3DIR="$2"
1031					shift ;;
1032				karatsuba-len=?*) karatsuba_len="$LONG_OPTARG" ;;
1033				karatsuba-len)
1034					if [ "$#" -lt 2 ]; then
1035						usage "No argument given for '--$arg' option"
1036					fi
1037					karatsuba_len="$1"
1038					shift ;;
1039				opt=?*) optimization="$LONG_OPTARG" ;;
1040				opt)
1041					if [ "$#" -lt 2 ]; then
1042						usage "No argument given for '--$arg' option"
1043					fi
1044					optimization="$1"
1045					shift ;;
1046				set-default-on=?*) set_default 1 "$LONG_OPTARG" ;;
1047				set-default-on)
1048					if [ "$#" -lt 2 ]; then
1049						usage "No argument given for '--$arg' option"
1050					fi
1051					set_default 1 "$1"
1052					shift ;;
1053				set-default-off=?*) set_default 0 "$LONG_OPTARG" ;;
1054				set-default-off)
1055					if [ "$#" -lt 2 ]; then
1056						usage "No argument given for '--$arg' option"
1057					fi
1058					set_default 0 "$1"
1059					shift ;;
1060				predefined-build-type=?*) predefined_build "$LONG_OPTARG" ;;
1061				predefined-build-type)
1062					if [ "$#" -lt 2 ]; then
1063						usage "No argument given for '--$arg' option"
1064					fi
1065					predefined_build "$1"
1066					shift ;;
1067				disable-bc) dc_only=1 ;;
1068				disable-dc) bc_only=1 ;;
1069				disable-clean) clean=0 ;;
1070				disable-extra-math) extra_math=0 ;;
1071				disable-generated-tests) generate_tests=0 ;;
1072				disable-history) hist=0 ;;
1073				disable-man-pages) install_manpages=0 ;;
1074				disable-nls) nls=0 ;;
1075				disable-strip) strip_bin=0 ;;
1076				disable-problematic-tests) problematic_tests=0 ;;
1077				enable-editline) hist_impl="editline" ;;
1078				enable-readline) hist_impl="readline" ;;
1079				enable-internal-history) hist_impl="internal" ;;
1080				enable-test-timing) time_tests=1 ;;
1081				enable-valgrind) vg=1 ;;
1082				enable-fuzz-mode) fuzz=1 ;;
1083				enable-ossfuzz-mode) ossfuzz=1 ;;
1084				enable-memcheck) memcheck=1 ;;
1085				install-all-locales) all_locales=1 ;;
1086				help* | bc-only* | dc-only* | coverage* | debug*)
1087					usage "No arg allowed for --$arg option" ;;
1088				disable-bc* | disable-dc* | disable-clean*)
1089					usage "No arg allowed for --$arg option" ;;
1090				disable-extra-math*)
1091					usage "No arg allowed for --$arg option" ;;
1092				disable-generated-tests* | disable-history*)
1093					usage "No arg allowed for --$arg option" ;;
1094				disable-man-pages* | disable-nls* | disable-strip*)
1095					usage "No arg allowed for --$arg option" ;;
1096				disable-problematic-tests*)
1097					usage "No arg allowed for --$arg option" ;;
1098				enable-fuzz-mode* | enable-test-timing* | enable-valgrind*)
1099					usage "No arg allowed for --$arg option" ;;
1100				enable-memcheck* | install-all-locales*)
1101					usage "No arg allowed for --$arg option" ;;
1102				enable-editline* | enable-readline*)
1103					usage "No arg allowed for --$arg option" ;;
1104				enable-internal-history*)
1105					usage "No arg allowed for --$arg option" ;;
1106				'') break ;; # "--" terminates argument processing
1107				* ) usage "Invalid option $LONG_OPTARG" ;;
1108			esac
1109			shift
1110			OPTIND=1 ;;
1111		?) usage "Invalid option: $opt" ;;
1112	esac
1113
1114done
1115
1116# Sometimes, developers don't want configure.sh to do a config clean. But
1117# sometimes they do.
1118if [ "$clean" -ne 0 ]; then
1119	if [ -f ./Makefile ]; then
1120		make clean_config > /dev/null
1121	fi
1122fi
1123
1124# It is an error to say that bc only should be built and likewise for dc.
1125if [ "$bc_only" -eq 1 ] && [ "$dc_only" -eq 1 ]; then
1126	usage "Can only specify one of -b(-D) or -d(-B)"
1127fi
1128
1129# The library is mutually exclusive to the calculators, so it's an error to
1130# give an option for either of them.
1131if [ "$library" -ne 0 ]; then
1132	if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then
1133		usage "Must not specify -b(-D) or -d(-B) when building the library"
1134	fi
1135fi
1136
1137# KARATSUBA_LEN must be an integer and must be 16 or greater.
1138case $karatsuba_len in
1139	(*[!0-9]*|'') usage "KARATSUBA_LEN is not a number" ;;
1140	(*) ;;
1141esac
1142
1143if [ "$karatsuba_len" -lt 16 ]; then
1144	usage "KARATSUBA_LEN is less than 16"
1145fi
1146
1147set -e
1148
1149if [ -z "${LONG_BIT+set}" ]; then
1150	LONG_BIT_DEFINE=""
1151elif [ "$LONG_BIT" -lt 32 ]; then
1152	usage "LONG_BIT is less than 32"
1153else
1154	LONG_BIT_DEFINE="-DBC_LONG_BIT=$LONG_BIT"
1155fi
1156
1157if [ -z "$CC" ]; then
1158	CC="c99"
1159else
1160
1161	# I had users complain that, if they gave CFLAGS as part of CC, which
1162	# autotools allows in its braindead way, the build would fail with an error.
1163	# I don't like adjusting for autotools, but oh well. These lines puts the
1164	# stuff after the first space into CFLAGS.
1165	ccbase=$(basename "$CC")
1166	suffix=" *"
1167	prefix="* "
1168
1169	if [ "${ccbase%%$suffix}" != "$ccbase" ]; then
1170		ccflags="${ccbase#$prefix}"
1171		cc="${ccbase%%$suffix}"
1172		ccdir=$(dirname "$CC")
1173		if [ "$ccdir" = "." ] && [ "${CC#.}" = "$CC" ]; then
1174			ccdir=""
1175		else
1176			ccdir="$ccdir/"
1177		fi
1178		CC="${ccdir}${cc}"
1179		CFLAGS="$CFLAGS $ccflags"
1180	fi
1181fi
1182
1183if [ -z "$HOSTCC" ] && [ -z "$HOST_CC" ]; then
1184	HOSTCC="$CC"
1185elif [ -z "$HOSTCC" ]; then
1186	HOSTCC="$HOST_CC"
1187fi
1188
1189if [ "$HOSTCC" != "$CC" ]; then
1190
1191	# Like above, this splits HOSTCC and HOSTCFLAGS.
1192	ccbase=$(basename "$HOSTCC")
1193	suffix=" *"
1194	prefix="* "
1195
1196	if [ "${ccbase%%$suffix}" != "$ccbase" ]; then
1197		ccflags="${ccbase#$prefix}"
1198		cc="${ccbase%%$suffix}"
1199		ccdir=$(dirname "$HOSTCC")
1200		if [ "$ccdir" = "." ] && [ "${HOSTCC#.}" = "$HOSTCC" ]; then
1201			ccdir=""
1202		else
1203			ccdir="$ccdir/"
1204		fi
1205		HOSTCC="${ccdir}${cc}"
1206		HOSTCFLAGS="$HOSTCFLAGS $ccflags"
1207	fi
1208fi
1209
1210if [ -z "${HOSTCFLAGS+set}" ] && [ -z "${HOST_CFLAGS+set}" ]; then
1211	HOSTCFLAGS="$CFLAGS"
1212elif [ -z "${HOSTCFLAGS+set}" ]; then
1213	HOSTCFLAGS="$HOST_CFLAGS"
1214fi
1215
1216# Store these for the cross compilation detection later.
1217OLDCFLAGS="$CFLAGS"
1218OLDHOSTCFLAGS="$HOSTCFLAGS"
1219
1220link="@printf 'No link necessary\\\\n'"
1221main_exec="BC"
1222executable="BC_EXEC"
1223
1224tests="test_bc timeconst test_dc"
1225
1226bc_test="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/all.sh bc $extra_math 1 $generate_tests $problematic_tests $time_tests \$(BC_EXEC)"
1227bc_test_np="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/all.sh -n bc $extra_math 1 $generate_tests $problematic_tests $time_tests \$(BC_EXEC)"
1228dc_test="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/all.sh dc $extra_math 1 $generate_tests $problematic_tests $time_tests \$(DC_EXEC)"
1229dc_test_np="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/all.sh -n dc $extra_math 1 $generate_tests $problematic_tests $time_tests \$(DC_EXEC)"
1230
1231timeconst="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/bc/timeconst.sh \$(TESTSDIR)/bc/scripts/timeconst.bc \$(BC_EXEC)"
1232
1233# In order to have cleanup at exit, we need to be in
1234# debug mode, so don't run valgrind without that.
1235if [ "$vg" -ne 0 ]; then
1236	debug=1
1237	bc_test_exec='valgrind $(VALGRIND_ARGS) $(BC_EXEC)'
1238	dc_test_exec='valgrind $(VALGRIND_ARGS) $(DC_EXEC)'
1239	bcl_test_exec='valgrind $(VALGRIND_ARGS) $(BCL_TEST)'
1240else
1241	bc_test_exec='$(BC_EXEC)'
1242	dc_test_exec='$(DC_EXEC)'
1243	bcl_test_exec='$(BCL_TEST)'
1244fi
1245
1246test_bc_history_prereqs="test_bc_history_all"
1247test_dc_history_prereqs="test_dc_history_all"
1248
1249karatsuba="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
1250karatsuba_test="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
1251
1252bc_lib="\$(GEN_DIR)/lib.o"
1253bc_help="\$(GEN_DIR)/bc_help.o"
1254dc_help="\$(GEN_DIR)/dc_help.o"
1255
1256default_target_prereqs="\$(BIN) \$(OBJS)"
1257default_target_cmd="\$(CC) \$(CFLAGS) \$(OBJS) \$(LDFLAGS) -o \$(EXEC)"
1258default_target="\$(DC_EXEC)"
1259
1260second_target_prereqs=""
1261second_target_cmd="$default_target_cmd"
1262second_target="\$(BC_EXEC)"
1263
1264# This if/else if chain is for setting the defaults that change based on whether
1265# the library is being built, bc only, dc only, or both calculators.
1266if [ "$library" -ne 0 ]; then
1267
1268	extra_math=1
1269	nls=0
1270	hist=0
1271	bc=1
1272	dc=1
1273
1274	default_target_prereqs="\$(BIN) \$(OBJ)"
1275	default_target_cmd="ar -r -cu \$(LIBBC) \$(OBJ)"
1276	default_target="\$(LIBBC)"
1277	tests="test_library"
1278	test_bc_history_prereqs=" test_bc_history_skip"
1279	test_dc_history_prereqs=" test_dc_history_skip"
1280
1281	install_prereqs=" install_library"
1282	uninstall_prereqs=" uninstall_library"
1283	install_man_prereqs=" install_bcl_manpage"
1284	uninstall_man_prereqs=" uninstall_bcl_manpage"
1285
1286elif [ "$bc_only" -eq 1 ]; then
1287
1288	bc=1
1289	dc=0
1290
1291	dc_help=""
1292
1293	executables="bc"
1294
1295	dc_test="@printf 'No dc tests to run\\\\n'"
1296	dc_test_np="@printf 'No dc tests to run\\\\n'"
1297	test_dc_history_prereqs=" test_dc_history_skip"
1298
1299	install_prereqs=" install_execs"
1300	install_man_prereqs=" install_bc_manpage"
1301	uninstall_prereqs=" uninstall_bc"
1302	uninstall_man_prereqs=" uninstall_bc_manpage"
1303
1304	default_target="\$(BC_EXEC)"
1305	second_target="\$(DC_EXEC)"
1306	tests="test_bc timeconst"
1307
1308elif [ "$dc_only" -eq 1 ]; then
1309
1310	bc=0
1311	dc=1
1312
1313	bc_lib=""
1314	bc_help=""
1315
1316	executables="dc"
1317
1318	main_exec="DC"
1319	executable="DC_EXEC"
1320
1321	bc_test="@printf 'No bc tests to run\\\\n'"
1322	bc_test_np="@printf 'No bc tests to run\\\\n'"
1323	test_bc_history_prereqs=" test_bc_history_skip"
1324
1325	timeconst="@printf 'timeconst cannot be run because bc is not built\\\\n'"
1326
1327	install_prereqs=" install_execs"
1328	install_man_prereqs=" install_dc_manpage"
1329	uninstall_prereqs=" uninstall_dc"
1330	uninstall_man_prereqs=" uninstall_dc_manpage"
1331
1332	tests="test_dc"
1333
1334elif [ "$ossfuzz" -eq 1 ]; then
1335
1336	if [ "$bc_only" -ne 0 ] || [ "$dc_only" -ne 0 ]; then
1337		usage "An OSS-Fuzz build must build both fuzzers."
1338	fi
1339
1340	bc=1
1341	dc=1
1342
1343	# Expressions *cannot* exit in an OSS-Fuzz build.
1344	bc_default_expr_exit=0
1345	dc_default_expr_exit=0
1346
1347	executables="bc_fuzzer and dc_fuzzer"
1348
1349	karatsuba="@\$(KARATSUBA) 30 0 \$(BC_EXEC)"
1350	karatsuba_test="@\$(KARATSUBA) 1 100 \$(BC_EXEC)"
1351
1352	if [ "$library" -eq 0 ]; then
1353		install_prereqs=" install_execs"
1354		install_man_prereqs=" install_bc_manpage install_dc_manpage"
1355		uninstall_prereqs=" uninstall_bc uninstall_dc"
1356		uninstall_man_prereqs=" uninstall_bc_manpage uninstall_dc_manpage"
1357	else
1358		install_prereqs=" install_library install_bcl_header"
1359		install_man_prereqs=" install_bcl_manpage"
1360		uninstall_prereqs=" uninstall_library uninstall_bcl_header"
1361		uninstall_man_prereqs=" uninstall_bcl_manpage"
1362		tests="test_library"
1363	fi
1364
1365	second_target_prereqs="src/bc_fuzzer.o $default_target_prereqs"
1366	default_target_prereqs="\$(BC_FUZZER) src/dc_fuzzer.o $default_target_prereqs"
1367	default_target_cmd="\$(CXX) \$(CFLAGS) src/dc_fuzzer.o \$(LIB_FUZZING_ENGINE) \$(OBJS) \$(LDFLAGS) -o \$(DC_FUZZER) \&\& ln -sf ./dc_fuzzer_c \$(DC_FUZZER_C)"
1368	second_target_cmd="\$(CXX) \$(CFLAGS) src/bc_fuzzer.o \$(LIB_FUZZING_ENGINE) \$(OBJS) \$(LDFLAGS) -o \$(BC_FUZZER) \&\& ln -sf ./bc_fuzzer_c \$(BC_FUZZER_C)"
1369
1370	default_target="\$(DC_FUZZER) \$(DC_FUZZER_C)"
1371	second_target="\$(BC_FUZZER) \$(BC_FUZZER_C)"
1372
1373else
1374
1375	bc=1
1376	dc=1
1377
1378	executables="bc and dc"
1379
1380	karatsuba="@\$(KARATSUBA) 30 0 \$(BC_EXEC)"
1381	karatsuba_test="@\$(KARATSUBA) 1 100 \$(BC_EXEC)"
1382
1383	if [ "$library" -eq 0 ]; then
1384		install_prereqs=" install_execs"
1385		install_man_prereqs=" install_bc_manpage install_dc_manpage"
1386		uninstall_prereqs=" uninstall_bc uninstall_dc"
1387		uninstall_man_prereqs=" uninstall_bc_manpage uninstall_dc_manpage"
1388	else
1389		install_prereqs=" install_library install_bcl_header"
1390		install_man_prereqs=" install_bcl_manpage"
1391		uninstall_prereqs=" uninstall_library uninstall_bcl_header"
1392		uninstall_man_prereqs=" uninstall_bcl_manpage"
1393		tests="test_library"
1394	fi
1395
1396	second_target_prereqs="$default_target_prereqs"
1397	default_target_prereqs="$second_target"
1398	default_target_cmd="\$(LINK) \$(BIN) \$(EXEC_PREFIX)\$(DC)"
1399
1400fi
1401
1402if [ "$fuzz" -ne 0 ] && [ "$ossfuzz" -ne 0 ]; then
1403	usage "Fuzzing mode and OSS-Fuzz mode are mutually exclusive"
1404fi
1405
1406# We need specific stuff for fuzzing.
1407if [ "$fuzz" -ne 0 ] || [ "$ossfuzz" -ne 0 ]; then
1408	debug=1
1409	hist=0
1410	nls=0
1411	optimization="3"
1412fi
1413
1414# This sets some necessary things for debug mode.
1415if [ "$debug" -eq 1 ]; then
1416
1417	if [ -z "$CFLAGS" ] && [ -z "$optimization" ]; then
1418		CFLAGS="-O0"
1419	fi
1420
1421	CFLAGS="-g $CFLAGS"
1422
1423else
1424	CPPFLAGS="-DNDEBUG $CPPFLAGS"
1425fi
1426
1427# Set optimization CFLAGS.
1428if [ -n "$optimization" ]; then
1429	CFLAGS="-O$optimization $CFLAGS"
1430fi
1431
1432# Set test coverage defaults.
1433if [ "$coverage" -eq 1 ]; then
1434
1435	if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then
1436		usage "Can only specify -c without -b or -d"
1437	fi
1438
1439	CFLAGS="-fprofile-arcs -ftest-coverage -g -O0 $CFLAGS"
1440	CPPFLAGS="-DNDEBUG $CPPFLAGS"
1441
1442	COVERAGE_OUTPUT="@gcov -pabcdf \$(GCDA) \$(BC_GCDA) \$(DC_GCDA) \$(HISTORY_GCDA) \$(RAND_GCDA)"
1443	COVERAGE_OUTPUT="$COVERAGE_OUTPUT;\$(RM) -f \$(GEN)*.gc*"
1444	COVERAGE_OUTPUT="$COVERAGE_OUTPUT;gcovr --exclude-unreachable-branches --exclude-throw-branches --html-details --output index.html"
1445	COVERAGE_PREREQS=" test coverage_output"
1446
1447else
1448	COVERAGE_OUTPUT="@printf 'Coverage not generated\\\\n'"
1449	COVERAGE_PREREQS=""
1450fi
1451
1452# Set some defaults.
1453if [ -z "${DESTDIR+set}" ]; then
1454	destdir=""
1455else
1456	destdir="DESTDIR = $DESTDIR"
1457fi
1458
1459# defprefix is for a warning about locales later.
1460if [ -z "${PREFIX+set}" ]; then
1461	PREFIX="/usr/local"
1462	defprefix=1
1463else
1464	defprefix=0
1465fi
1466
1467if [ -z "${BINDIR+set}" ]; then
1468	BINDIR="$PREFIX/bin"
1469fi
1470
1471if [ -z "${INCLUDEDIR+set}" ]; then
1472	INCLUDEDIR="$PREFIX/include"
1473fi
1474
1475if [ -z "${LIBDIR+set}" ]; then
1476	LIBDIR="$PREFIX/lib"
1477fi
1478
1479if [ -z "${PC_PATH+set}" ]; then
1480
1481	set +e
1482
1483	command -v pkg-config > /dev/null
1484	err=$?
1485
1486	set -e
1487
1488	if [ "$err" -eq 0 ]; then
1489		PC_PATH=$(pkg-config --variable=pc_path pkg-config)
1490		PC_PATH="${PC_PATH%%:*}"
1491	else
1492		PC_PATH=""
1493	fi
1494
1495fi
1496
1497# Set a default for the DATAROOTDIR. This is done if either manpages will be
1498# installed, or locales are enabled because that's probably where NLSPATH
1499# points.
1500if [ "$install_manpages" -ne 0 ] || [ "$nls" -ne 0 ]; then
1501	if [ -z "${DATAROOTDIR+set}" ]; then
1502		DATAROOTDIR="$PREFIX/share"
1503	fi
1504fi
1505
1506# Set defaults for manpage environment variables.
1507if [ "$install_manpages" -ne 0 ]; then
1508
1509	if [ -z "${DATADIR+set}" ]; then
1510		DATADIR="$DATAROOTDIR"
1511	fi
1512
1513	if [ -z "${MANDIR+set}" ]; then
1514		MANDIR="$DATADIR/man"
1515	fi
1516
1517	if [ -z "${MAN1DIR+set}" ]; then
1518		MAN1DIR="$MANDIR/man1"
1519	fi
1520
1521	if [ -z "${MAN3DIR+set}" ]; then
1522		MAN3DIR="$MANDIR/man3"
1523	fi
1524
1525else
1526	install_man_prereqs=""
1527	uninstall_man_prereqs=""
1528fi
1529
1530# Here is where we test NLS (the locale system). This is done by trying to
1531# compile src/vm.c, which has the relevant code. If it fails, then it is
1532# disabled.
1533if [ "$nls" -ne 0 ]; then
1534
1535	set +e
1536
1537	printf 'Testing NLS...\n'
1538
1539	flags="-DBC_ENABLE_NLS=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
1540	flags="$flags -DBC_ENABLE_HISTORY=$hist -DBC_ENABLE_LIBRARY=0 -DBC_ENABLE_AFL=0"
1541	flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -DBC_ENABLE_OSSFUZZ=0"
1542	flags="$flags -I$scriptdir/include/ -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
1543
1544	ccbase=$(basename "$CC")
1545
1546	if [ "$ccbase" = "clang" ]; then
1547		flags="$flags -Wno-unreachable-code"
1548	fi
1549
1550	"$CC" $CPPFLAGS $CFLAGS $flags -c "$scriptdir/src/vm.c" -E > /dev/null
1551
1552	err="$?"
1553
1554	rm -rf "./vm.o"
1555
1556	# If this errors, it is probably because of building on Windows or musl,
1557	# and NLS is not supported on Windows or musl, so disable it.
1558	if [ "$err" -ne 0 ]; then
1559		printf 'NLS does not work.\n'
1560		if [ $force -eq 0 ]; then
1561			printf 'Disabling NLS...\n\n'
1562			nls=0
1563		else
1564			printf 'Forcing NLS...\n\n'
1565		fi
1566	else
1567		printf 'NLS works.\n\n'
1568
1569		printf 'Testing gencat...\n'
1570		gencat "./en_US.cat" "$scriptdir/locales/en_US.msg" > /dev/null
1571
1572		err="$?"
1573
1574		rm -rf "./en_US.cat"
1575
1576		if [ "$err" -ne 0 ]; then
1577			printf 'gencat does not work.\n'
1578			if [ $force -eq 0 ]; then
1579				printf 'Disabling NLS...\n\n'
1580				nls=0
1581			else
1582				printf 'Forcing NLS...\n\n'
1583			fi
1584		else
1585
1586			printf 'gencat works.\n\n'
1587
1588			# It turns out that POSIX locales are really terrible, and running
1589			# gencat on one machine is not guaranteed to make those cat files
1590			# portable to another machine, so we had better warn the user here.
1591			if [ "$HOSTCC" != "$CC" ] || [ "$OLDHOSTCFLAGS" != "$OLDCFLAGS" ]; then
1592				printf 'Cross-compile detected.\n\n'
1593				printf 'WARNING: Catalog files generated with gencat may not be portable\n'
1594				printf '         across different architectures.\n\n'
1595			fi
1596
1597			if [ -z "$NLSPATH" ]; then
1598				NLSPATH="/usr/share/locale/%L/%N"
1599			fi
1600
1601			install_locales_prereqs=" install_locales"
1602			uninstall_locales_prereqs=" uninstall_locales"
1603
1604		fi
1605
1606	fi
1607
1608	set -e
1609
1610else
1611	install_locales_prereqs=""
1612	uninstall_locales_prereqs=""
1613	all_locales=0
1614fi
1615
1616if [ "$nls" -ne 0 ] && [ "$all_locales" -ne 0 ]; then
1617	install_locales="\$(LOCALE_INSTALL) -l \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)"
1618else
1619	install_locales="\$(LOCALE_INSTALL) \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)"
1620fi
1621
1622# Like the above tested locale support, this tests history.
1623if [ "$hist" -eq 1 ]; then
1624
1625	if [ "$hist_impl" = "editline" ]; then
1626		editline=1
1627		readline=0
1628	elif [ "$hist_impl" = "readline" ]; then
1629		editline=0
1630		readline=1
1631	else
1632		editline=0
1633		readline=0
1634	fi
1635
1636	set +e
1637
1638	printf 'Testing history...\n'
1639
1640	flags="-DBC_ENABLE_HISTORY=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
1641	flags="$flags -DBC_ENABLE_NLS=$nls -DBC_ENABLE_LIBRARY=0 -DBC_ENABLE_AFL=0"
1642	flags="$flags -DBC_ENABLE_EDITLINE=$editline -DBC_ENABLE_READLINE=$readline"
1643	flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -DBC_ENABLE_OSSFUZZ=0"
1644	flags="$flags -I$scriptdir/include/ -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
1645
1646	"$CC" $CPPFLAGS $CFLAGS $flags -c "$scriptdir/src/history.c" -E > /dev/null
1647
1648	err="$?"
1649
1650	rm -rf "./history.o"
1651
1652	# If this errors, it is probably because of building on Windows,
1653	# and history is not supported on Windows, so disable it.
1654	if [ "$err" -ne 0 ]; then
1655		printf 'History does not work.\n'
1656		if [ $force -eq 0 ]; then
1657			printf 'Disabling history...\n\n'
1658			hist=0
1659		else
1660			printf 'Forcing history...\n\n'
1661		fi
1662	else
1663		printf 'History works.\n\n'
1664	fi
1665
1666	set -e
1667
1668else
1669
1670	editline=0
1671	readline=0
1672
1673fi
1674
1675# We have to disable the history tests if it is disabled or valgrind is on. Or
1676# if we are using editline or readline.
1677if [ "$hist" -eq 0 ] || [ "$vg" -ne 0 ]; then
1678	test_bc_history_prereqs=" test_bc_history_skip"
1679	test_dc_history_prereqs=" test_dc_history_skip"
1680	history_tests="@printf 'Skipping history tests...\\\\n'"
1681	CFLAGS="$CFLAGS -DBC_ENABLE_EDITLINE=0 -DBC_ENABLE_READLINE=0"
1682else
1683
1684	if [ "$editline" -eq 0 ] && [ "$readline" -eq 0 ]; then
1685		history_tests="@printf '\$(TEST_STARS)\\\\n\\\\nRunning history tests...\\\\n\\\\n'"
1686		history_tests="$history_tests \&\& \$(TESTSDIR)/history.sh bc -a \&\&"
1687		history_tests="$history_tests \$(TESTSDIR)/history.sh dc -a \&\& printf"
1688		history_tests="$history_tests '\\\\nAll history tests passed.\\\\n\\\\n\$(TEST_STARS)\\\\n'"
1689	else
1690		test_bc_history_prereqs=" test_bc_history_skip"
1691		test_dc_history_prereqs=" test_dc_history_skip"
1692		history_tests="@printf 'Skipping history tests...\\\\n'"
1693	fi
1694
1695	# We are also setting the CFLAGS and LDFLAGS here.
1696	if [ "$editline" -ne 0 ]; then
1697		LDFLAGS="$LDFLAGS -ledit"
1698		CPPFLAGS="$CPPFLAGS -DBC_ENABLE_EDITLINE=1 -DBC_ENABLE_READLINE=0"
1699	elif [ "$readline" -ne 0 ]; then
1700		LDFLAGS="$LDFLAGS -lreadline"
1701		CPPFLAGS="$CPPFLAGS -DBC_ENABLE_EDITLINE=0 -DBC_ENABLE_READLINE=1"
1702	else
1703		CPPFLAGS="$CPPFLAGS -DBC_ENABLE_EDITLINE=0 -DBC_ENABLE_READLINE=0"
1704	fi
1705
1706fi
1707
1708# Test FreeBSD. This is not in an if statement because regardless of whatever
1709# the user says, we need to know if we are on FreeBSD. If we are, we cannot set
1710# _POSIX_C_SOURCE and _XOPEN_SOURCE. The FreeBSD headers turn *off* stuff when
1711# that is done.
1712set +e
1713printf 'Testing for FreeBSD...\n'
1714
1715flags="-DBC_TEST_FREEBSD -DBC_ENABLE_AFL=0"
1716"$CC" $CPPFLAGS $CFLAGS $flags "-I$scriptdir/include" -E "$scriptdir/scripts/os.c" > /dev/null
1717
1718err="$?"
1719
1720if [ "$err" -ne 0 ]; then
1721	printf 'On FreeBSD. Not using _POSIX_C_SOURCE and _XOPEN_SOURCE.\n\n'
1722else
1723	printf 'Not on FreeBSD. Using _POSIX_C_SOURCE and _XOPEN_SOURCE.\n\n'
1724	CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
1725fi
1726
1727# Test macOS. This is not in an if statement because regardless of whatever the
1728# user says, we need to know if we are on macOS. If we are, we have to set
1729# _DARWIN_C_SOURCE.
1730printf 'Testing for macOS...\n'
1731
1732flags="-DBC_TEST_APPLE -DBC_ENABLE_AFL=0"
1733"$CC" $CPPFLAGS $CFLAGS $flags "-I$scriptdir/include" -E "$scriptdir/scripts/os.c" > /dev/null
1734
1735err="$?"
1736
1737if [ "$err" -ne 0 ]; then
1738	printf 'On macOS. Using _DARWIN_C_SOURCE.\n\n'
1739	apple="-D_DARWIN_C_SOURCE"
1740else
1741	printf 'Not on macOS.\n\n'
1742	apple=""
1743fi
1744
1745# We can't use the linker's strip flag on macOS.
1746if [ "$debug" -eq 0 ] && [ "$apple" = "" ] && [ "$strip_bin" -ne 0 ]; then
1747	LDFLAGS="-s $LDFLAGS"
1748fi
1749
1750# Test OpenBSD. This is not in an if statement because regardless of whatever
1751# the user says, we need to know if we are on OpenBSD to activate _BSD_SOURCE.
1752# No, I cannot `#define _BSD_SOURCE` in a header because OpenBSD's patched GCC
1753# and Clang complain that that is only allowed for system headers. Sigh....So we
1754# have to check at configure time and set it on the compiler command-line. And
1755# we have to set it because we also set _POSIX_C_SOURCE, which OpenBSD headers
1756# detect, and when they detect it, they turn off _BSD_SOURCE unless it is
1757# specifically requested.
1758printf 'Testing for OpenBSD...\n'
1759
1760flags="-DBC_TEST_OPENBSD -DBC_ENABLE_AFL=0"
1761"$CC" $CPPFLAGS $CFLAGS $flags "-I$scriptdir/include" -E "$scriptdir/scripts/os.c" > /dev/null
1762
1763err="$?"
1764
1765if [ "$err" -ne 0 ]; then
1766
1767	printf 'On OpenBSD. Using _BSD_SOURCE.\n\n'
1768	bsd="-D_BSD_SOURCE"
1769
1770	# Readline errors on OpenBSD, for some weird reason.
1771	if [ "$readline" -ne 0 ]; then
1772		usage "Cannot use readline on OpenBSD"
1773	fi
1774
1775else
1776	printf 'Not on OpenBSD.\n\n'
1777	bsd=""
1778fi
1779
1780set -e
1781
1782if [ "$library" -eq 1 ]; then
1783	bc_lib=""
1784fi
1785
1786if [ "$extra_math" -eq 1 ] && [ "$bc" -ne 0 ] && [ "$library" -eq 0 ]; then
1787	BC_LIB2_O="\$(GEN_DIR)/lib2.o"
1788else
1789	BC_LIB2_O=""
1790fi
1791
1792GEN_DIR="$scriptdir/gen"
1793
1794# These lines set the appropriate targets based on whether `gen/strgen.c` or
1795# `gen/strgen.sh` is used.
1796GEN="strgen"
1797GEN_EXEC_TARGET="\$(HOSTCC) -DBC_ENABLE_AFL=0 -DBC_ENABLE_OSSFUZZ=0 -I$scriptdir/include/ \$(HOSTCFLAGS) -o \$(GEN_EXEC) \$(GEN_C)"
1798CLEAN_PREREQS=" clean_gen clean_coverage"
1799
1800if [ -z "${GEN_HOST+set}" ]; then
1801	GEN_HOST=1
1802else
1803	if [ "$GEN_HOST" -eq 0 ]; then
1804		GEN="strgen.sh"
1805		GEN_EXEC_TARGET="@printf 'Do not need to build gen/strgen.c\\\\n'"
1806		CLEAN_PREREQS=" clean_coverage"
1807	fi
1808fi
1809
1810# The fuzzer files are always unneeded because they'll be built separately.
1811manpage_args=""
1812unneeded="bc_fuzzer.c dc_fuzzer.c"
1813headers="\$(HEADERS)"
1814
1815# This series of if statements figure out what source files are *not* needed.
1816if [ "$extra_math" -eq 0 ]; then
1817	exclude_extra_math=1
1818	manpage_args="E"
1819	unneeded="$unneeded rand.c"
1820else
1821	exclude_extra_math=0
1822	headers="$headers \$(EXTRA_MATH_HEADERS)"
1823fi
1824
1825# All of these next if statements set the build type and mark certain source
1826# files as unneeded so that they won't have targets generated for them.
1827
1828if [ "$hist" -eq 0 ]; then
1829	manpage_args="${manpage_args}H"
1830	unneeded="$unneeded history.c"
1831else
1832	headers="$headers \$(HISTORY_HEADERS)"
1833fi
1834
1835if [ "$nls" -eq 0 ]; then
1836	manpage_args="${manpage_args}N"
1837fi
1838
1839if [ "$bc" -eq 0 ]; then
1840	unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
1841else
1842	headers="$headers \$(BC_HEADERS)"
1843fi
1844
1845if [ "$dc" -eq 0 ]; then
1846	unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
1847else
1848	headers="$headers \$(DC_HEADERS)"
1849fi
1850
1851# This convoluted mess does pull the version out. If you change the format of
1852# include/version.h, you may have to change this line.
1853version=$(cat "$scriptdir/include/version.h" | grep "VERSION " - | awk '{ print $3 }' -)
1854
1855if [ "$library" -ne 0 ]; then
1856
1857	unneeded="$unneeded args.c opt.c read.c file.c main.c"
1858	unneeded="$unneeded lang.c lex.c parse.c program.c"
1859	unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
1860	unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
1861	headers="$headers \$(LIBRARY_HEADERS)"
1862
1863	if [ "$PC_PATH" != "" ]; then
1864
1865		contents=$(cat "$scriptdir/bcl.pc.in")
1866
1867		contents=$(replace "$contents" "INCLUDEDIR" "$INCLUDEDIR")
1868		contents=$(replace "$contents" "LIBDIR" "$LIBDIR")
1869		contents=$(replace "$contents" "VERSION" "$version")
1870
1871		printf '%s\n' "$contents" > "$scriptdir/bcl.pc"
1872
1873		pkg_config_install="\$(SAFE_INSTALL) \$(PC_INSTALL_ARGS) \"\$(BCL_PC)\" \"\$(DESTDIR)\$(PC_PATH)/\$(BCL_PC)\""
1874		pkg_config_uninstall="\$(RM) -f \"\$(DESTDIR)\$(PC_PATH)/\$(BCL_PC)\""
1875
1876	else
1877
1878		pkg_config_install=""
1879		pkg_config_uninstall=""
1880
1881	fi
1882
1883elif [ "$ossfuzz" -ne 0 ]; then
1884
1885	unneeded="$unneeded library.c main.c"
1886
1887	PC_PATH=""
1888	pkg_config_install=""
1889	pkg_config_uninstall=""
1890
1891else
1892
1893	unneeded="$unneeded library.c"
1894
1895	PC_PATH=""
1896	pkg_config_install=""
1897	pkg_config_uninstall=""
1898
1899fi
1900
1901# library.c, bc_fuzzer.c, and dc_fuzzer.c are not needed under normal
1902# circumstances.
1903if [ "$unneeded" = "" ]; then
1904	unneeded="library.c bc_fuzzer.c dc_fuzzer.c"
1905fi
1906
1907# This sets the appropriate manpage for a full build.
1908if [ "$manpage_args" = "" ]; then
1909	manpage_args="A"
1910fi
1911
1912if [ "$vg" -ne 0 ] || [ "$ossfuzz" -ne 0 ]; then
1913	memcheck=1
1914fi
1915
1916if [ "$bc_default_prompt" = "" ]; then
1917	bc_default_prompt="$bc_default_tty_mode"
1918fi
1919
1920if [ "$dc_default_prompt" = "" ]; then
1921	dc_default_prompt="$dc_default_tty_mode"
1922fi
1923
1924# Generate the test targets and prerequisites.
1925bc_tests=$(gen_std_test_targets bc)
1926bc_script_tests=$(gen_script_test_targets bc)
1927bc_err_tests=$(gen_err_test_targets bc)
1928dc_tests=$(gen_std_test_targets dc)
1929dc_script_tests=$(gen_script_test_targets dc)
1930dc_err_tests=$(gen_err_test_targets dc)
1931
1932printf 'unneeded: %s\n' "$unneeded"
1933
1934# Print out the values; this is for debugging.
1935printf 'Version: %s\n' "$version"
1936
1937if [ "$bc" -ne 0 ]; then
1938	printf 'Building bc\n'
1939else
1940	printf 'Not building bc\n'
1941fi
1942if [ "$dc" -ne 0 ]; then
1943	printf 'Building dc\n'
1944else
1945	printf 'Not building dc\n'
1946fi
1947printf '\n'
1948printf 'BC_ENABLE_LIBRARY=%s\n\n' "$library"
1949printf 'BC_ENABLE_HISTORY=%s\n' "$hist"
1950printf 'BC_ENABLE_EXTRA_MATH=%s\n' "$extra_math"
1951printf 'BC_ENABLE_NLS=%s\n\n' "$nls"
1952printf 'BC_ENABLE_AFL=%s\n' "$fuzz"
1953printf '\n'
1954printf 'BC_NUM_KARATSUBA_LEN=%s\n' "$karatsuba_len"
1955printf '\n'
1956printf 'CC=%s\n' "$CC"
1957printf 'CFLAGS=%s\n' "$CFLAGS"
1958printf 'HOSTCC=%s\n' "$HOSTCC"
1959printf 'HOSTCFLAGS=%s\n' "$HOSTCFLAGS"
1960printf 'CPPFLAGS=%s\n' "$CPPFLAGS"
1961printf 'LDFLAGS=%s\n' "$LDFLAGS"
1962printf 'PREFIX=%s\n' "$PREFIX"
1963printf 'BINDIR=%s\n' "$BINDIR"
1964printf 'INCLUDEDIR=%s\n' "$INCLUDEDIR"
1965printf 'LIBDIR=%s\n' "$LIBDIR"
1966printf 'DATAROOTDIR=%s\n' "$DATAROOTDIR"
1967printf 'DATADIR=%s\n' "$DATADIR"
1968printf 'MANDIR=%s\n' "$MANDIR"
1969printf 'MAN1DIR=%s\n' "$MAN1DIR"
1970printf 'MAN3DIR=%s\n' "$MAN3DIR"
1971printf 'NLSPATH=%s\n' "$NLSPATH"
1972printf 'PC_PATH=%s\n' "$PC_PATH"
1973printf 'EXECSUFFIX=%s\n' "$EXECSUFFIX"
1974printf 'EXECPREFIX=%s\n' "$EXECPREFIX"
1975printf 'DESTDIR=%s\n' "$DESTDIR"
1976printf 'LONG_BIT=%s\n' "$LONG_BIT"
1977printf 'GEN_HOST=%s\n' "$GEN_HOST"
1978printf 'GEN_EMU=%s\n' "$GEN_EMU"
1979printf '\n'
1980printf 'Setting Defaults\n'
1981printf '================\n'
1982printf 'bc.banner=%s\n' "$bc_default_banner"
1983printf 'bc.sigint_reset=%s\n' "$bc_default_sigint_reset"
1984printf 'dc.sigint_reset=%s\n' "$dc_default_sigint_reset"
1985printf 'bc.tty_mode=%s\n' "$bc_default_tty_mode"
1986printf 'dc.tty_mode=%s\n' "$dc_default_tty_mode"
1987printf 'bc.prompt=%s\n' "$bc_default_prompt"
1988printf 'dc.prompt=%s\n' "$dc_default_prompt"
1989printf 'bc.expr_exit=%s\n' "$bc_default_expr_exit"
1990printf 'dc.expr_exit=%s\n' "$dc_default_expr_exit"
1991printf 'bc.digit_clamp=%s\n' "$bc_default_digit_clamp"
1992printf 'dc.digit_clamp=%s\n' "$dc_default_digit_clamp"
1993
1994# This code outputs a warning. The warning is to not surprise users when locales
1995# are installed outside of the prefix. This warning is suppressed when the
1996# default prefix is used, as well, so as not to panic users just installing by
1997# hand. I believe this will be okay because NLSPATH is usually in /usr and the
1998# default prefix is /usr/local, so they'll be close that way.
1999if [ "$nls" -ne 0 ] && [ "${NLSPATH#$PREFIX}" = "${NLSPATH}" ] && [ "$defprefix" -eq 0 ]; then
2000	printf '\n********************************************************************************\n\n'
2001	printf 'WARNING: Locales will *NOT* be installed in $PREFIX (%s).\n' "$PREFIX"
2002	printf '\n'
2003	printf '         This is because they *MUST* be installed at a fixed location to even\n'
2004	printf '         work, and that fixed location is $NLSPATH (%s).\n' "$NLSPATH"
2005	printf '\n'
2006	printf '         This location is *outside* of $PREFIX. If you do not wish to install\n'
2007	printf '         locales outside of $PREFIX, you must disable NLS with the -N or the\n'
2008	printf '         --disable-nls options.\n'
2009	printf '\n'
2010	printf '         The author apologizes for the inconvenience, but the need to install\n'
2011	printf '         the locales at a fixed location is mandated by POSIX, and it is not\n'
2012	printf '         possible for the author to change that requirement.\n'
2013	printf '\n********************************************************************************\n'
2014fi
2015
2016# This is where the real work begins. This is the point at which the Makefile.in
2017# template is edited and output to the Makefile.
2018
2019contents=$(cat "$scriptdir/Makefile.in")
2020
2021needle="WARNING"
2022replacement='*** WARNING: Autogenerated from Makefile.in. DO NOT MODIFY ***'
2023
2024contents=$(replace "$contents" "$needle" "$replacement")
2025
2026# The contents are edited to have the list of files to build.
2027contents=$(gen_file_list "$contents" $unneeded)
2028
2029SRC_TARGETS=""
2030
2031# This line and loop generates the individual targets for source files. I used
2032# to just use an implicit target, but that was found to be inadequate when I
2033# added the library.
2034src_files=$(find_src_files $unneeded)
2035
2036for f in $src_files; do
2037	o=$(replace_ext "$f" "c" "o")
2038	o=$(basename "$o")
2039	SRC_TARGETS=$(printf '%s\n\nsrc/%s: src %s %s\n\t$(CC) $(CFLAGS) -o src/%s -c %s\n' \
2040		"$SRC_TARGETS" "$o" "$headers" "$f" "$o" "$f")
2041done
2042
2043# Replace all the placeholders.
2044contents=$(replace "$contents" "ROOTDIR" "$scriptdir")
2045contents=$(replace "$contents" "BUILDDIR" "$builddir")
2046
2047contents=$(replace "$contents" "HEADERS" "$headers")
2048
2049contents=$(replace "$contents" "BC_ENABLED" "$bc")
2050contents=$(replace "$contents" "DC_ENABLED" "$dc")
2051
2052contents=$(replace "$contents" "BC_ALL_TESTS" "$bc_test")
2053contents=$(replace "$contents" "BC_ALL_TESTS_NP" "$bc_test_np")
2054contents=$(replace "$contents" "BC_TESTS" "$bc_tests")
2055contents=$(replace "$contents" "BC_SCRIPT_TESTS" "$bc_script_tests")
2056contents=$(replace "$contents" "BC_ERROR_TESTS" "$bc_err_tests")
2057contents=$(replace "$contents" "BC_TEST_EXEC" "$bc_test_exec")
2058contents=$(replace "$contents" "TIMECONST_ALL_TESTS" "$timeconst")
2059
2060contents=$(replace "$contents" "DC_ALL_TESTS" "$dc_test")
2061contents=$(replace "$contents" "DC_ALL_TESTS_NP" "$dc_test_np")
2062contents=$(replace "$contents" "DC_TESTS" "$dc_tests")
2063contents=$(replace "$contents" "DC_SCRIPT_TESTS" "$dc_script_tests")
2064contents=$(replace "$contents" "DC_ERROR_TESTS" "$dc_err_tests")
2065contents=$(replace "$contents" "DC_TEST_EXEC" "$dc_test_exec")
2066
2067contents=$(replace "$contents" "BCL_TEST_EXEC" "$bcl_test_exec")
2068
2069contents=$(replace "$contents" "BUILD_TYPE" "$manpage_args")
2070contents=$(replace "$contents" "EXCLUDE_EXTRA_MATH" "$exclude_extra_math")
2071
2072contents=$(replace "$contents" "LIBRARY" "$library")
2073contents=$(replace "$contents" "HISTORY" "$hist")
2074contents=$(replace "$contents" "EXTRA_MATH" "$extra_math")
2075contents=$(replace "$contents" "NLS" "$nls")
2076contents=$(replace "$contents" "FUZZ" "$fuzz")
2077contents=$(replace "$contents" "OSSFUZZ" "$ossfuzz")
2078contents=$(replace "$contents" "MEMCHECK" "$memcheck")
2079contents=$(replace "$contents" "LIB_FUZZING_ENGINE" "$LIB_FUZZING_ENGINE")
2080
2081contents=$(replace "$contents" "BC_LIB_O" "$bc_lib")
2082contents=$(replace "$contents" "BC_HELP_O" "$bc_help")
2083contents=$(replace "$contents" "DC_HELP_O" "$dc_help")
2084contents=$(replace "$contents" "BC_LIB2_O" "$BC_LIB2_O")
2085contents=$(replace "$contents" "KARATSUBA_LEN" "$karatsuba_len")
2086
2087contents=$(replace "$contents" "NLSPATH" "$NLSPATH")
2088contents=$(replace "$contents" "DESTDIR" "$destdir")
2089contents=$(replace "$contents" "EXECSUFFIX" "$EXECSUFFIX")
2090contents=$(replace "$contents" "EXECPREFIX" "$EXECPREFIX")
2091contents=$(replace "$contents" "BINDIR" "$BINDIR")
2092contents=$(replace "$contents" "INCLUDEDIR" "$INCLUDEDIR")
2093contents=$(replace "$contents" "LIBDIR" "$LIBDIR")
2094contents=$(replace "$contents" "MAN1DIR" "$MAN1DIR")
2095contents=$(replace "$contents" "MAN3DIR" "$MAN3DIR")
2096contents=$(replace "$contents" "CFLAGS" "$CFLAGS")
2097contents=$(replace "$contents" "HOSTCFLAGS" "$HOSTCFLAGS")
2098contents=$(replace "$contents" "CPPFLAGS" "$CPPFLAGS")
2099contents=$(replace "$contents" "LDFLAGS" "$LDFLAGS")
2100contents=$(replace "$contents" "CC" "$CC")
2101contents=$(replace "$contents" "HOSTCC" "$HOSTCC")
2102contents=$(replace "$contents" "COVERAGE_OUTPUT" "$COVERAGE_OUTPUT")
2103contents=$(replace "$contents" "COVERAGE_PREREQS" "$COVERAGE_PREREQS")
2104contents=$(replace "$contents" "INSTALL_PREREQS" "$install_prereqs")
2105contents=$(replace "$contents" "INSTALL_MAN_PREREQS" "$install_man_prereqs")
2106contents=$(replace "$contents" "INSTALL_LOCALES" "$install_locales")
2107contents=$(replace "$contents" "INSTALL_LOCALES_PREREQS" "$install_locales_prereqs")
2108contents=$(replace "$contents" "UNINSTALL_MAN_PREREQS" "$uninstall_man_prereqs")
2109contents=$(replace "$contents" "UNINSTALL_PREREQS" "$uninstall_prereqs")
2110contents=$(replace "$contents" "UNINSTALL_LOCALES_PREREQS" "$uninstall_locales_prereqs")
2111
2112contents=$(replace "$contents" "PC_PATH" "$PC_PATH")
2113contents=$(replace "$contents" "PKG_CONFIG_INSTALL" "$pkg_config_install")
2114contents=$(replace "$contents" "PKG_CONFIG_UNINSTALL" "$pkg_config_uninstall")
2115
2116contents=$(replace "$contents" "DEFAULT_TARGET" "$default_target")
2117contents=$(replace "$contents" "DEFAULT_TARGET_PREREQS" "$default_target_prereqs")
2118contents=$(replace "$contents" "DEFAULT_TARGET_CMD" "$default_target_cmd")
2119contents=$(replace "$contents" "SECOND_TARGET" "$second_target")
2120contents=$(replace "$contents" "SECOND_TARGET_PREREQS" "$second_target_prereqs")
2121contents=$(replace "$contents" "SECOND_TARGET_CMD" "$second_target_cmd")
2122
2123contents=$(replace "$contents" "ALL_PREREQ" "$ALL_PREREQ")
2124contents=$(replace "$contents" "BC_EXEC_PREREQ" "$bc_exec_prereq")
2125contents=$(replace "$contents" "BC_EXEC_CMD" "$bc_exec_cmd")
2126contents=$(replace "$contents" "DC_EXEC_PREREQ" "$dc_exec_prereq")
2127contents=$(replace "$contents" "DC_EXEC_CMD" "$dc_exec_cmd")
2128
2129contents=$(replace "$contents" "EXECUTABLES" "$executables")
2130contents=$(replace "$contents" "MAIN_EXEC" "$main_exec")
2131contents=$(replace "$contents" "EXEC" "$executable")
2132contents=$(replace "$contents" "TESTS" "$tests")
2133
2134contents=$(replace "$contents" "BC_HISTORY_TEST_PREREQS" "$test_bc_history_prereqs")
2135contents=$(replace "$contents" "DC_HISTORY_TEST_PREREQS" "$test_dc_history_prereqs")
2136contents=$(replace "$contents" "HISTORY_TESTS" "$history_tests")
2137
2138contents=$(replace "$contents" "VG_BC_TEST" "$vg_bc_test")
2139contents=$(replace "$contents" "VG_DC_TEST" "$vg_dc_test")
2140
2141contents=$(replace "$contents" "TIMECONST" "$timeconst")
2142
2143contents=$(replace "$contents" "KARATSUBA" "$karatsuba")
2144contents=$(replace "$contents" "KARATSUBA_TEST" "$karatsuba_test")
2145
2146contents=$(replace "$contents" "LONG_BIT_DEFINE" "$LONG_BIT_DEFINE")
2147
2148contents=$(replace "$contents" "GEN_DIR" "$GEN_DIR")
2149contents=$(replace "$contents" "GEN" "$GEN")
2150contents=$(replace "$contents" "GEN_EXEC_TARGET" "$GEN_EXEC_TARGET")
2151contents=$(replace "$contents" "CLEAN_PREREQS" "$CLEAN_PREREQS")
2152contents=$(replace "$contents" "GEN_EMU" "$GEN_EMU")
2153
2154contents=$(replace "$contents" "BSD" "$bsd")
2155contents=$(replace "$contents" "APPLE" "$apple")
2156
2157contents=$(replace "$contents" "BC_DEFAULT_BANNER" "$bc_default_banner")
2158contents=$(replace "$contents" "BC_DEFAULT_SIGINT_RESET" "$bc_default_sigint_reset")
2159contents=$(replace "$contents" "DC_DEFAULT_SIGINT_RESET" "$dc_default_sigint_reset")
2160contents=$(replace "$contents" "BC_DEFAULT_TTY_MODE" "$bc_default_tty_mode")
2161contents=$(replace "$contents" "DC_DEFAULT_TTY_MODE" "$dc_default_tty_mode")
2162contents=$(replace "$contents" "BC_DEFAULT_PROMPT" "$bc_default_prompt")
2163contents=$(replace "$contents" "DC_DEFAULT_PROMPT" "$dc_default_prompt")
2164contents=$(replace "$contents" "BC_DEFAULT_EXPR_EXIT" "$bc_default_expr_exit")
2165contents=$(replace "$contents" "DC_DEFAULT_EXPR_EXIT" "$dc_default_expr_exit")
2166contents=$(replace "$contents" "BC_DEFAULT_DIGIT_CLAMP" "$bc_default_digit_clamp")
2167contents=$(replace "$contents" "DC_DEFAULT_DIGIT_CLAMP" "$dc_default_digit_clamp")
2168
2169# Do the first print to the Makefile.
2170printf '%s\n%s\n\n' "$contents" "$SRC_TARGETS" > "Makefile"
2171
2172# Generate the individual test targets.
2173if [ "$bc" -ne 0 ]; then
2174	gen_std_tests bc "$extra_math" "$time_tests" $bc_test_exec
2175	gen_script_tests bc "$extra_math" "$generate_tests" "$time_tests" $bc_test_exec
2176	gen_err_tests bc $bc_test_exec
2177fi
2178
2179if [ "$dc" -ne 0 ]; then
2180	gen_std_tests dc "$extra_math" "$time_tests" $dc_test_exec
2181	gen_script_tests dc "$extra_math" "$generate_tests" "$time_tests" $dc_test_exec
2182	gen_err_tests dc $dc_test_exec
2183fi
2184
2185if [ "$ossfuzz" -ne 0 ]; then
2186
2187	printf 'bc_fuzzer_c: $(BC_FUZZER)\n\tln -sf $(BC_FUZZER) bc_fuzzer_c\n' >> Makefile
2188	printf 'bc_fuzzer_C: $(BC_FUZZER)\n\tln -sf $(BC_FUZZER) bc_fuzzer_C\n' >> Makefile
2189	printf 'dc_fuzzer_c: $(DC_FUZZER)\n\tln -sf $(DC_FUZZER) dc_fuzzer_c\n' >> Makefile
2190	printf 'dc_fuzzer_C: $(DC_FUZZER)\n\tln -sf $(DC_FUZZER) dc_fuzzer_C\n' >> Makefile
2191
2192fi
2193
2194# Copy the correct manuals to the expected places.
2195mkdir -p manuals
2196cp -f "$scriptdir/manuals/bc/$manpage_args.1.md" manuals/bc.1.md
2197cp -f "$scriptdir/manuals/bc/$manpage_args.1" manuals/bc.1
2198cp -f "$scriptdir/manuals/dc/$manpage_args.1.md" manuals/dc.1.md
2199cp -f "$scriptdir/manuals/dc/$manpage_args.1" manuals/dc.1
2200
2201make clean > /dev/null
2202