xref: /freebsd/contrib/bc/configure.sh (revision c66ec88fed842fbaad62c30d510644ceb7bd2d71)
1#! /bin/sh
2#
3# SPDX-License-Identifier: BSD-2-Clause
4#
5# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions are met:
9#
10# * Redistributions of source code must retain the above copyright notice, this
11#   list of conditions and the following disclaimer.
12#
13# * Redistributions in binary form must reproduce the above copyright notice,
14#   this list of conditions and the following disclaimer in the documentation
15#   and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27# POSSIBILITY OF SUCH DAMAGE.
28#
29
30script="$0"
31scriptdir=$(dirname "$script")
32script=$(basename "$script")
33
34. "$scriptdir/functions.sh"
35
36usage() {
37
38	if [ $# -gt 0 ]; then
39
40		_usage_val=1
41
42		printf "%s\n\n" "$1"
43
44	else
45		_usage_val=0
46	fi
47
48	printf 'usage:\n'
49	printf '    %s -h\n' "$script"
50	printf '    %s --help\n' "$script"
51	printf '    %s [-a|-bD|-dB|-c] [-EfgGHlMNPT] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\n' "$script"
52	printf '    %s \\\n' "$script"
53	printf '       [--library|--bc-only --disable-dc|--dc-only --disable-bc|--coverage]\\\n'
54	printf '       [--force --debug --disable-extra-math --disable-generated-tests]    \\\n'
55	printf '       [--disable-history --disable-man-pages --disable-nls]               \\\n'
56	printf '       [--disable-prompt --disable-strip] [--install-all-locales]          \\\n'
57	printf '       [--opt=OPT_LEVEL] [--karatsuba-len=KARATSUBA_LEN]                   \\\n'
58	printf '       [--prefix=PREFIX] [--bindir=BINDIR] [--datarootdir=DATAROOTDIR]     \\\n'
59	printf '       [--datadir=DATADIR] [--mandir=MANDIR] [--man1dir=MAN1DIR]           \\\n'
60	printf '\n'
61	printf '    -a, --library\n'
62	printf '        Build the libbc instead of the programs. This is meant to be used with\n'
63	printf '        Other software like programming languages that want to make use of the\n'
64	printf '        parsing and math capabilities. This option will install headers using\n'
65	printf '        `make install`.\n'
66	printf '    -b, --bc-only\n'
67	printf '        Build bc only. It is an error if "-d", "--dc-only", "-B", or\n'
68	printf '        "--disable-bc" are specified too.\n'
69	printf '    -B, --disable-bc\n'
70	printf '        Disable bc. It is an error if "-b", "--bc-only", "-D", or "--disable-dc"\n'
71	printf '        are specified too.\n'
72	printf '    -c, --coverage\n'
73	printf '        Generate test coverage code. Requires gcov and regcovr.\n'
74	printf '        It is an error if either "-b" ("-D") or "-d" ("-B") is specified.\n'
75	printf '        Requires a compiler that use gcc-compatible coverage options\n'
76	printf '    -d, --dc-only\n'
77	printf '        Build dc only. It is an error if "-b", "--bc-only", "-D", or\n'
78	printf '        "--disable-dc" are specified too.\n'
79	printf '    -D, --disable-dc\n'
80	printf '        Disable dc. It is an error if "-d", "--dc-only", "-B", or "--disable-bc"\n'
81	printf '        are specified too.\n'
82	printf '    -E, --disable-extra-math\n'
83	printf '        Disable extra math. This includes: "$" operator (truncate to integer),\n'
84	printf '        "@" operator (set number of decimal places), and r(x, p) (rounding\n'
85	printf '        function). Additionally, this option disables the extra printing\n'
86	printf '        functions in the math library.\n'
87	printf '    -f, --force\n'
88	printf '        Force use of all enabled options, even if they do not work. This\n'
89	printf '        option is to allow the maintainer a way to test that certain options\n'
90	printf '        are not failing invisibly. (Development only.)'
91	printf '    -g, --debug\n'
92	printf '        Build in debug mode. Adds the "-g" flag, and if there are no\n'
93	printf '        other CFLAGS, and "-O" was not given, this also adds the "-O0"\n'
94	printf '        flag. If this flag is *not* given, "-DNDEBUG" is added to CPPFLAGS\n'
95	printf '        and a strip flag is added to the link stage.\n'
96	printf '    -G, --disable-generated-tests\n'
97	printf '        Disable generating tests. This is for platforms that do not have a\n'
98	printf '        GNU bc-compatible bc to generate tests.\n'
99	printf '    -h, --help\n'
100	printf '        Print this help message and exit.\n'
101	printf '    -H, --disable-history\n'
102	printf '        Disable history.\n'
103	printf '    -k KARATSUBA_LEN, --karatsuba-len KARATSUBA_LEN\n'
104	printf '        Set the karatsuba length to KARATSUBA_LEN (default is 64).\n'
105	printf '        It is an error if KARATSUBA_LEN is not a number or is less than 16.\n'
106	printf '    -l, --install-all-locales\n'
107	printf '        Installs all locales, regardless of how many are on the system. This\n'
108	printf '        option is useful for package maintainers who want to make sure that\n'
109	printf '        a package contains all of the locales that end users might need.\n'
110	printf '    -M, --disable-man-pages\n'
111	printf '        Disable installing manpages.\n'
112	printf '    -N, --disable-nls\n'
113	printf '        Disable POSIX locale (NLS) support.\n'
114	printf '    -O OPT_LEVEL, --opt OPT_LEVEL\n'
115	printf '        Set the optimization level. This can also be included in the CFLAGS,\n'
116	printf '        but it is provided, so maintainers can build optimized debug builds.\n'
117	printf '        This is passed through to the compiler, so it must be supported.\n'
118	printf '    -P, --disable-prompt\n'
119	printf '        Disables the prompt in the built bc. The prompt will never show up,\n'
120	printf '        or in other words, it will be permanently disabled and cannot be\n'
121	printf '        enabled.\n'
122	printf '    -T, --disable-strip\n'
123	printf '        Disable stripping symbols from the compiled binary or binaries.\n'
124	printf '        Stripping symbols only happens when debug mode is off.\n'
125	printf '    --prefix PREFIX\n'
126	printf '        The prefix to install to. Overrides "$PREFIX" if it exists.\n'
127	printf '        If PREFIX is "/usr", install path will be "/usr/bin".\n'
128	printf '        Default is "/usr/local".\n'
129	printf '    --bindir BINDIR\n'
130	printf '        The directory to install binaries in. Overrides "$BINDIR" if it exists.\n'
131	printf '        Default is "$PREFIX/bin".\n'
132	printf '    --includedir INCLUDEDIR\n'
133	printf '        The directory to install headers in. Overrides "$INCLUDEDIR" if it\n'
134	printf '        exists. Default is "$PREFIX/include".\n'
135	printf '    --libdir LIBDIR\n'
136	printf '        The directory to install libraries in. Overrides "$LIBDIR" if it exists.\n'
137	printf '        Default is "$PREFIX/lib".\n'
138	printf '    --datarootdir DATAROOTDIR\n'
139	printf '        The root location for data files. Overrides "$DATAROOTDIR" if it exists.\n'
140	printf '        Default is "$PREFIX/share".\n'
141	printf '    --datadir DATADIR\n'
142	printf '        The location for data files. Overrides "$DATADIR" if it exists.\n'
143	printf '        Default is "$DATAROOTDIR".\n'
144	printf '    --mandir MANDIR\n'
145	printf '        The location to install manpages to. Overrides "$MANDIR" if it exists.\n'
146	printf '        Default is "$DATADIR/man".\n'
147	printf '    --man1dir MAN1DIR\n'
148	printf '        The location to install Section 1 manpages to. Overrides "$MAN1DIR" if\n'
149	printf '        it exists. Default is "$MANDIR/man1".\n'
150	printf '    --man3dir MAN3DIR\n'
151	printf '        The location to install Section 3 manpages to. Overrides "$MAN3DIR" if\n'
152	printf '        it exists. Default is "$MANDIR/man3".\n'
153	printf '\n'
154	printf 'In addition, the following environment variables are used:\n'
155	printf '\n'
156	printf '    CC           C compiler. Must be compatible with POSIX c99. If there is a\n'
157	printf '                 space in the basename of the compiler, the items after the\n'
158	printf '                 first space are assumed to be compiler flags, and in that case,\n'
159	printf '                 the flags are automatically moved into CFLAGS. Default is\n'
160	printf '                 "c99".\n'
161	printf '    HOSTCC       Host C compiler. Must be compatible with POSIX c99. If there is\n'
162	printf '                 a space in the basename of the compiler, the items after the\n'
163	printf '                 first space are assumed to be compiler flags, and in the case,\n'
164	printf '                 the flags are automatically moved into HOSTCFLAGS. Default is\n'
165	printf '                 "$CC".\n'
166	printf '    HOST_CC      Same as HOSTCC. If HOSTCC also exists, it is used.\n'
167	printf '    CFLAGS       C compiler flags.\n'
168	printf '    HOSTCFLAGS   CFLAGS for HOSTCC. Default is "$CFLAGS".\n'
169	printf '    HOST_CFLAGS  Same as HOST_CFLAGS. If HOST_CFLAGS also exists, it is used.\n'
170	printf '    CPPFLAGS     C preprocessor flags. Default is "".\n'
171	printf '    LDFLAGS      Linker flags. Default is "".\n'
172	printf '    PREFIX       The prefix to install to. Default is "/usr/local".\n'
173	printf '                 If PREFIX is "/usr", install path will be "/usr/bin".\n'
174	printf '    BINDIR       The directory to install binaries in. Default is "$PREFIX/bin".\n'
175	printf '    INCLUDEDIR   The directory to install header files in. Default is\n'
176	printf '                 "$PREFIX/include".\n'
177	printf '    LIBDIR       The directory to install libraries in. Default is\n'
178	printf '                 "$PREFIX/lib".\n'
179	printf '    DATAROOTDIR  The root location for data files. Default is "$PREFIX/share".\n'
180	printf '    DATADIR      The location for data files. Default is "$DATAROOTDIR".\n'
181	printf '    MANDIR       The location to install manpages to. Default is "$DATADIR/man".\n'
182	printf '    MAN1DIR      The location to install Section 1 manpages to. Default is\n'
183	printf '                 "$MANDIR/man1".\n'
184	printf '    MAN3DIR      The location to install Section 3 manpages to. Default is\n'
185	printf '                 "$MANDIR/man3".\n'
186	printf '    NLSPATH      The location to install locale catalogs to. Must be an absolute\n'
187	printf '                 path (or contain one). This is treated the same as the POSIX\n'
188	printf '                 definition of $NLSPATH (see POSIX environment variables for\n'
189	printf '                 more information). Default is "/usr/share/locale/%%L/%%N".\n'
190	printf '    EXECSUFFIX   The suffix to append to the executable names, used to not\n'
191	printf '                 interfere with other installed bc executables. Default is "".\n'
192	printf '    EXECPREFIX   The prefix to append to the executable names, used to not\n'
193	printf '                 interfere with other installed bc executables. Default is "".\n'
194	printf '    DESTDIR      For package creation. Default is "". If it is empty when\n'
195	printf '                 `%s` is run, it can also be passed to `make install`\n' "$script"
196	printf '                 later as an environment variable. If both are specified,\n'
197	printf '                 the one given to `%s` takes precedence.\n' "$script"
198	printf '    LONG_BIT     The number of bits in a C `long` type. This is mostly for the\n'
199	printf '                 embedded space since this `bc` uses `long`s internally for\n'
200	printf '                 overflow checking. In C99, a `long` is required to be 32 bits.\n'
201	printf '                 For most normal desktop systems, setting this is unnecessary,\n'
202	printf '                 except that 32-bit platforms with 64-bit longs may want to set\n'
203	printf '                 it to `32`. Default is the default of `LONG_BIT` for the target\n'
204	printf '                 platform. Minimum allowed is `32`. It is a build time error if\n'
205	printf '                 the specified value of `LONG_BIT` is greater than the default\n'
206	printf '                 value of `LONG_BIT` for the target platform.\n'
207	printf '    GEN_HOST     Whether to use `gen/strgen.c`, instead of `gen/strgen.sh`, to\n'
208	printf '                 produce the C files that contain the help texts as well as the\n'
209	printf '                 math libraries. By default, `gen/strgen.c` is used, compiled by\n'
210	printf '                 "$HOSTCC" and run on the host machine. Using `gen/strgen.sh`\n'
211	printf '                 removes the need to compile and run an executable on the host\n'
212	printf '                 machine since `gen/strgen.sh` is a POSIX shell script. However,\n'
213	printf '                 `gen/lib2.bc` is perilously close to 4095 characters, the max\n'
214	printf '                 supported length of a string literal in C99 (and it could be\n'
215	printf '                 added to in the future), and `gen/strgen.sh` generates a string\n'
216	printf '                 literal instead of an array, as `gen/strgen.c` does. For most\n'
217	printf '                 production-ready compilers, this limit probably is not\n'
218	printf '                 enforced, but it could be. Both options are still available for\n'
219	printf '                 this reason. If you are sure your compiler does not have the\n'
220	printf '                 limit and do not want to compile and run a binary on the host\n'
221	printf '                 machine, set this variable to "0". Any other value, or a\n'
222	printf '                 non-existent value, will cause the build system to compile and\n'
223	printf '                 run `gen/strgen.c`. Default is "".\n'
224	printf '    GEN_EMU      Emulator to run string generator code under (leave empty if not\n'
225	printf '                 necessary). This is not necessary when using `gen/strgen.sh`.\n'
226	printf '                 Default is "".\n'
227	printf '\n'
228	printf 'WARNING: even though `configure.sh` supports both option types, short and\n'
229	printf 'long, it does not support handling both at the same time. Use only one type.\n'
230
231	exit "$_usage_val"
232}
233
234replace_ext() {
235
236	if [ "$#" -ne 3 ]; then
237		err_exit "Invalid number of args to $0"
238	fi
239
240	_replace_ext_file="$1"
241	_replace_ext_ext1="$2"
242	_replace_ext_ext2="$3"
243
244	_replace_ext_result=${_replace_ext_file%.$_replace_ext_ext1}.$_replace_ext_ext2
245
246	printf '%s\n' "$_replace_ext_result"
247}
248
249replace_exts() {
250
251	if [ "$#" -ne 3 ]; then
252		err_exit "Invalid number of args to $0"
253	fi
254
255	_replace_exts_files="$1"
256	_replace_exts_ext1="$2"
257	_replace_exts_ext2="$3"
258
259	for _replace_exts_file in $_replace_exts_files; do
260		_replace_exts_new_name=$(replace_ext "$_replace_exts_file" "$_replace_exts_ext1" "$_replace_exts_ext2")
261		_replace_exts_result="$_replace_exts_result $_replace_exts_new_name"
262	done
263
264	printf '%s\n' "$_replace_exts_result"
265}
266
267replace() {
268
269	if [ "$#" -ne 3 ]; then
270		err_exit "Invalid number of args to $0"
271	fi
272
273	_replace_str="$1"
274	_replace_needle="$2"
275	_replace_replacement="$3"
276
277	substring_replace "$_replace_str" "%%$_replace_needle%%" "$_replace_replacement"
278}
279
280gen_file_list() {
281
282	if [ "$#" -lt 1 ]; then
283		err_exit "Invalid number of args to $0"
284	fi
285
286	_gen_file_list_contents="$1"
287	shift
288
289	p=$(pwd)
290
291	cd "$scriptdir"
292
293	if [ "$#" -ge 1 ]; then
294
295		while [ "$#" -ge 1 ]; do
296			a="$1"
297			shift
298			args="$args ! -path src/${a}"
299		done
300
301	else
302		args="-print"
303	fi
304
305	_gen_file_list_needle_src="SRC"
306	_gen_file_list_needle_obj="OBJ"
307	_gen_file_list_needle_gcda="GCDA"
308	_gen_file_list_needle_gcno="GCNO"
309
310	_gen_file_list_replacement=$(find src/ -depth -name "*.c" $args | tr '\n' ' ')
311	_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
312		"$_gen_file_list_needle_src" "$_gen_file_list_replacement")
313
314	_gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "c" "o")
315	_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
316		"$_gen_file_list_needle_obj" "$_gen_file_list_replacement")
317
318	_gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "o" "gcda")
319	_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
320		"$_gen_file_list_needle_gcda" "$_gen_file_list_replacement")
321
322	_gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "gcda" "gcno")
323	_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
324		"$_gen_file_list_needle_gcno" "$_gen_file_list_replacement")
325
326	cd "$p"
327
328	printf '%s\n' "$_gen_file_list_contents"
329}
330
331bc_only=0
332dc_only=0
333coverage=0
334karatsuba_len=32
335debug=0
336hist=1
337extra_math=1
338optimization=""
339generate_tests=1
340install_manpages=1
341nls=1
342prompt=1
343force=0
344strip_bin=1
345all_locales=0
346library=0
347
348while getopts "abBcdDEfgGhHk:lMNO:PST-" opt; do
349
350	case "$opt" in
351		a) library=1 ;;
352		b) bc_only=1 ;;
353		B) dc_only=1 ;;
354		c) coverage=1 ;;
355		d) dc_only=1 ;;
356		D) bc_only=1 ;;
357		E) extra_math=0 ;;
358		f) force=1 ;;
359		g) debug=1 ;;
360		G) generate_tests=0 ;;
361		h) usage ;;
362		H) hist=0 ;;
363		k) karatsuba_len="$OPTARG" ;;
364		l) all_locales=1 ;;
365		M) install_manpages=0 ;;
366		N) nls=0 ;;
367		O) optimization="$OPTARG" ;;
368		P) prompt=0 ;;
369		T) strip_bin=0 ;;
370		-)
371			arg="$1"
372			arg="${arg#--}"
373			LONG_OPTARG="${arg#*=}"
374			case $arg in
375				help) usage ;;
376				library) library=1 ;;
377				bc-only) bc_only=1 ;;
378				dc-only) dc_only=1 ;;
379				coverage) coverage=1 ;;
380				debug) debug=1 ;;
381				force) force=1 ;;
382				prefix=?*) PREFIX="$LONG_OPTARG" ;;
383				prefix)
384					if [ "$#" -lt 2 ]; then
385						usage "No argument given for '--$arg' option"
386					fi
387					PREFIX="$2"
388					shift ;;
389				bindir=?*) BINDIR="$LONG_OPTARG" ;;
390				bindir)
391					if [ "$#" -lt 2 ]; then
392						usage "No argument given for '--$arg' option"
393					fi
394					BINDIR="$2"
395					shift ;;
396				includedir=?*) INCLUDEDIR="$LONG_OPTARG" ;;
397				includedir)
398					if [ "$#" -lt 2 ]; then
399						usage "No argument given for '--$arg' option"
400					fi
401					INCLUDEDIR="$2"
402					shift ;;
403				libdir=?*) LIBDIR="$LONG_OPTARG" ;;
404				libdir)
405					if [ "$#" -lt 2 ]; then
406						usage "No argument given for '--$arg' option"
407					fi
408					LIBDIR="$2"
409					shift ;;
410				datarootdir=?*) DATAROOTDIR="$LONG_OPTARG" ;;
411				datarootdir)
412					if [ "$#" -lt 2 ]; then
413						usage "No argument given for '--$arg' option"
414					fi
415					DATAROOTDIR="$2"
416					shift ;;
417				datadir=?*) DATADIR="$LONG_OPTARG" ;;
418				datadir)
419					if [ "$#" -lt 2 ]; then
420						usage "No argument given for '--$arg' option"
421					fi
422					DATADIR="$2"
423					shift ;;
424				mandir=?*) MANDIR="$LONG_OPTARG" ;;
425				mandir)
426					if [ "$#" -lt 2 ]; then
427						usage "No argument given for '--$arg' option"
428					fi
429					MANDIR="$2"
430					shift ;;
431				man1dir=?*) MAN1DIR="$LONG_OPTARG" ;;
432				man1dir)
433					if [ "$#" -lt 2 ]; then
434						usage "No argument given for '--$arg' option"
435					fi
436					MAN1DIR="$2"
437					shift ;;
438				man3dir=?*) MAN3DIR="$LONG_OPTARG" ;;
439				man3dir)
440					if [ "$#" -lt 2 ]; then
441						usage "No argument given for '--$arg' option"
442					fi
443					MAN3DIR="$2"
444					shift ;;
445				localedir=?*) LOCALEDIR="$LONG_OPTARG" ;;
446				localedir)
447					if [ "$#" -lt 2 ]; then
448						usage "No argument given for '--$arg' option"
449					fi
450					LOCALEDIR="$2"
451					shift ;;
452				karatsuba-len=?*) karatsuba_len="$LONG_OPTARG" ;;
453				karatsuba-len)
454					if [ "$#" -lt 2 ]; then
455						usage "No argument given for '--$arg' option"
456					fi
457					karatsuba_len="$1"
458					shift ;;
459				opt=?*) optimization="$LONG_OPTARG" ;;
460				opt)
461					if [ "$#" -lt 2 ]; then
462						usage "No argument given for '--$arg' option"
463					fi
464					optimization="$1"
465					shift ;;
466				disable-bc) dc_only=1 ;;
467				disable-dc) bc_only=1 ;;
468				disable-extra-math) extra_math=0 ;;
469				disable-generated-tests) generate_tests=0 ;;
470				disable-history) hist=0 ;;
471				disable-man-pages) install_manpages=0 ;;
472				disable-nls) nls=0 ;;
473				disable-prompt) prompt=0 ;;
474				disable-strip) strip_bin=0 ;;
475				install-all-locales) all_locales=1 ;;
476				help* | bc-only* | dc-only* | coverage* | debug*)
477					usage "No arg allowed for --$arg option" ;;
478				disable-bc* | disable-dc* | disable-extra-math*)
479					usage "No arg allowed for --$arg option" ;;
480				disable-generated-tests* | disable-history*)
481					usage "No arg allowed for --$arg option" ;;
482				disable-man-pages* | disable-nls* | disable-strip*)
483					usage "No arg allowed for --$arg option" ;;
484				install-all-locales*)
485					usage "No arg allowed for --$arg option" ;;
486				'') break ;; # "--" terminates argument processing
487				* ) usage "Invalid option $LONG_OPTARG" ;;
488			esac
489			shift
490			OPTIND=1 ;;
491		?) usage "Invalid option $opt" ;;
492	esac
493
494done
495
496if [ "$bc_only" -eq 1 ] && [ "$dc_only" -eq 1 ]; then
497	usage "Can only specify one of -b(-D) or -d(-B)"
498fi
499
500if [ "$library" -ne 0 ]; then
501	if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then
502		usage "Must not specify -b(-D) or -d(-B) when building the library"
503	fi
504fi
505
506case $karatsuba_len in
507	(*[!0-9]*|'') usage "KARATSUBA_LEN is not a number" ;;
508	(*) ;;
509esac
510
511if [ "$karatsuba_len" -lt 16 ]; then
512	usage "KARATSUBA_LEN is less than 16"
513fi
514
515set -e
516
517if [ -z "${LONG_BIT+set}" ]; then
518	LONG_BIT_DEFINE=""
519elif [ "$LONG_BIT" -lt 32 ]; then
520	usage "LONG_BIT is less than 32"
521else
522	LONG_BIT_DEFINE="-DBC_LONG_BIT=\$(BC_LONG_BIT)"
523fi
524
525if [ -z "$CC" ]; then
526	CC="c99"
527else
528	ccbase=$(basename "$CC")
529	suffix=" *"
530	prefix="* "
531
532	if [ "${ccbase%%$suffix}" != "$ccbase" ]; then
533		ccflags="${ccbase#$prefix}"
534		cc="${ccbase%%$suffix}"
535		ccdir=$(dirname "$CC")
536		if [ "$ccdir" = "." ] && [ "${CC#.}" = "$CC" ]; then
537			ccdir=""
538		else
539			ccdir="$ccdir/"
540		fi
541		CC="${ccdir}${cc}"
542		CFLAGS="$CFLAGS $ccflags"
543	fi
544fi
545
546if [ -z "$HOSTCC" ] && [ -z "$HOST_CC" ]; then
547	HOSTCC="$CC"
548elif [ -z "$HOSTCC" ]; then
549	HOSTCC="$HOST_CC"
550fi
551
552if [ "$HOSTCC" != "$CC" ]; then
553	ccbase=$(basename "$HOSTCC")
554	suffix=" *"
555	prefix="* "
556
557	if [ "${ccbase%%$suffix}" != "$ccbase" ]; then
558		ccflags="${ccbase#$prefix}"
559		cc="${ccbase%%$suffix}"
560		ccdir=$(dirname "$HOSTCC")
561		if [ "$ccdir" = "." ] && [ "${HOSTCC#.}" = "$HOSTCC" ]; then
562			ccdir=""
563		else
564			ccdir="$ccdir/"
565		fi
566		HOSTCC="${ccdir}${cc}"
567		HOSTCFLAGS="$HOSTCFLAGS $ccflags"
568	fi
569fi
570
571if [ -z "${HOSTCFLAGS+set}" ] && [ -z "${HOST_CFLAGS+set}" ]; then
572	HOSTCFLAGS="$CFLAGS"
573elif [ -z "${HOSTCFLAGS+set}" ]; then
574	HOSTCFLAGS="$HOST_CFLAGS"
575fi
576
577link="@printf 'No link necessary\\\\n'"
578main_exec="BC"
579executable="BC_EXEC"
580
581tests="test_bc timeconst test_dc"
582
583bc_test="@tests/all.sh bc $extra_math 1 $generate_tests 0 \$(BC_EXEC)"
584bc_time_test="@tests/all.sh bc $extra_math 1 $generate_tests 1 \$(BC_EXEC)"
585
586dc_test="@tests/all.sh dc $extra_math 1 $generate_tests 0 \$(DC_EXEC)"
587dc_time_test="@tests/all.sh dc $extra_math 1 $generate_tests 1 \$(DC_EXEC)"
588
589timeconst="@tests/bc/timeconst.sh tests/bc/scripts/timeconst.bc \$(BC_EXEC)"
590
591# In order to have cleanup at exit, we need to be in
592# debug mode, so don't run valgrind without that.
593if [ "$debug" -ne 0 ]; then
594	vg_bc_test="@tests/all.sh bc $extra_math 1 $generate_tests 0 valgrind \$(VALGRIND_ARGS) \$(BC_EXEC)"
595	vg_dc_test="@tests/all.sh dc $extra_math 1 $generate_tests 0 valgrind \$(VALGRIND_ARGS) \$(DC_EXEC)"
596else
597	vg_bc_test="@printf 'Cannot run valgrind without debug flags\\\\n'"
598	vg_dc_test="@printf 'Cannot run valgrind without debug flags\\\\n'"
599fi
600
601karatsuba="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
602karatsuba_test="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
603
604bc_lib="\$(GEN_DIR)/lib.o"
605bc_help="\$(GEN_DIR)/bc_help.o"
606dc_help="\$(GEN_DIR)/dc_help.o"
607
608if [ "$bc_only" -eq 1 ]; then
609
610	bc=1
611	dc=0
612
613	dc_help=""
614
615	executables="bc"
616
617	dc_test="@printf 'No dc tests to run\\\\n'"
618	dc_time_test="@printf 'No dc tests to run\\\\n'"
619	vg_dc_test="@printf 'No dc tests to run\\\\n'"
620
621	install_prereqs=" install_execs"
622	install_man_prereqs=" install_bc_manpage"
623	uninstall_prereqs=" uninstall_bc"
624	uninstall_man_prereqs=" uninstall_bc_manpage"
625
626elif [ "$dc_only" -eq 1 ]; then
627
628	bc=0
629	dc=1
630
631	bc_lib=""
632	bc_help=""
633
634	executables="dc"
635
636	main_exec="DC"
637	executable="DC_EXEC"
638
639	bc_test="@printf 'No bc tests to run\\\\n'"
640	bc_time_test="@printf 'No bc tests to run\\\\n'"
641	vg_bc_test="@printf 'No bc tests to run\\\\n'"
642
643	timeconst="@printf 'timeconst cannot be run because bc is not built\\\\n'"
644
645	install_prereqs=" install_execs"
646	install_man_prereqs=" install_dc_manpage"
647	uninstall_prereqs=" uninstall_dc"
648	uninstall_man_prereqs=" uninstall_dc_manpage"
649
650else
651
652	bc=1
653	dc=1
654
655	executables="bc and dc"
656
657	link="\$(LINK) \$(BIN) \$(EXEC_PREFIX)\$(DC)"
658
659	karatsuba="@\$(KARATSUBA) 30 0 \$(BC_EXEC)"
660	karatsuba_test="@\$(KARATSUBA) 1 100 \$(BC_EXEC)"
661
662	if [ "$library" -eq 0 ]; then
663		install_prereqs=" install_execs"
664		install_man_prereqs=" install_bc_manpage install_dc_manpage"
665		uninstall_prereqs=" uninstall_bc uninstall_dc"
666		uninstall_man_prereqs=" uninstall_bc_manpage uninstall_dc_manpage"
667	else
668		install_prereqs=" install_library install_bcl_header"
669		install_man_prereqs=" install_bcl_manpage"
670		uninstall_prereqs=" uninstall_library uninstall_bcl_header"
671		uninstall_man_prereqs=" uninstall_bcl_manpage"
672		tests="test_library"
673	fi
674
675fi
676
677if [ "$debug" -eq 1 ]; then
678
679	if [ -z "$CFLAGS" ] && [ -z "$optimization" ]; then
680		CFLAGS="-O0"
681	fi
682
683	CFLAGS="-g $CFLAGS"
684
685else
686	CPPFLAGS="-DNDEBUG $CPPFLAGS"
687	if [ "$strip_bin" -ne 0 ]; then
688		LDFLAGS="-s $LDFLAGS"
689	fi
690fi
691
692if [ -n "$optimization" ]; then
693	CFLAGS="-O$optimization $CFLAGS"
694fi
695
696if [ "$coverage" -eq 1 ]; then
697
698	if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then
699		usage "Can only specify -c without -b or -d"
700	fi
701
702	CFLAGS="-fprofile-arcs -ftest-coverage -g -O0 $CFLAGS"
703	CPPFLAGS="-DNDEBUG $CPPFLAGS"
704
705	COVERAGE_OUTPUT="@gcov -pabcdf \$(GCDA) \$(BC_GCDA) \$(DC_GCDA) \$(HISTORY_GCDA) \$(RAND_GCDA)"
706	COVERAGE_OUTPUT="$COVERAGE_OUTPUT;\$(RM) -f \$(GEN)*.gc*"
707	COVERAGE_OUTPUT="$COVERAGE_OUTPUT;gcovr --html-details --output index.html"
708	COVERAGE_PREREQS=" test coverage_output"
709
710else
711	COVERAGE_OUTPUT="@printf 'Coverage not generated\\\\n'"
712	COVERAGE_PREREQS=""
713fi
714
715if [ -z "${DESTDIR+set}" ]; then
716	destdir=""
717else
718	destdir="DESTDIR = $DESTDIR"
719fi
720
721if [ -z "${PREFIX+set}" ]; then
722	PREFIX="/usr/local"
723fi
724
725if [ -z "${BINDIR+set}" ]; then
726	BINDIR="$PREFIX/bin"
727fi
728
729if [ -z "${INCLUDEDIR+set}" ]; then
730	INCLUDEDIR="$PREFIX/include"
731fi
732
733if [ -z "${LIBDIR+set}" ]; then
734	LIBDIR="$PREFIX/lib"
735fi
736
737if [ "$install_manpages" -ne 0 ] || [ "$nls" -ne 0 ]; then
738	if [ -z "${DATAROOTDIR+set}" ]; then
739		DATAROOTDIR="$PREFIX/share"
740	fi
741fi
742
743if [ "$install_manpages" -ne 0 ]; then
744
745	if [ -z "${DATADIR+set}" ]; then
746		DATADIR="$DATAROOTDIR"
747	fi
748
749	if [ -z "${MANDIR+set}" ]; then
750		MANDIR="$DATADIR/man"
751	fi
752
753	if [ -z "${MAN1DIR+set}" ]; then
754		MAN1DIR="$MANDIR/man1"
755	fi
756
757	if [ -z "${MAN3DIR+set}" ]; then
758		MAN3DIR="$MANDIR/man3"
759	fi
760
761else
762	install_man_prereqs=""
763	uninstall_man_prereqs=""
764fi
765
766if [ "$library" -ne 0 ]; then
767	extra_math=1
768	nls=0
769	hist=0
770	prompt=0
771	ALL_PREREQ="library"
772else
773	ALL_PREREQ="execs"
774fi
775
776if [ "$nls" -ne 0 ]; then
777
778	set +e
779
780	printf 'Testing NLS...\n'
781
782	flags="-DBC_ENABLE_NLS=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
783	flags="$flags -DBC_ENABLE_HISTORY=$hist"
784	flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/"
785	flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
786
787	"$CC" $CPPFLAGS $CFLAGS $flags -c "src/vm.c" -o "$scriptdir/vm.o" > /dev/null 2>&1
788
789	err="$?"
790
791	rm -rf "$scriptdir/vm.o"
792
793	# If this errors, it is probably because of building on Windows,
794	# and NLS is not supported on Windows, so disable it.
795	if [ "$err" -ne 0 ]; then
796		printf 'NLS does not work.\n'
797		if [ $force -eq 0 ]; then
798			printf 'Disabling NLS...\n\n'
799			nls=0
800		else
801			printf 'Forcing NLS...\n\n'
802		fi
803	else
804		printf 'NLS works.\n\n'
805
806		printf 'Testing gencat...\n'
807		gencat "$scriptdir/en_US.cat" "$scriptdir/locales/en_US.msg" > /dev/null 2>&1
808
809		err="$?"
810
811		rm -rf "$scriptdir/en_US.cat"
812
813		if [ "$err" -ne 0 ]; then
814			printf 'gencat does not work.\n'
815			if [ $force -eq 0 ]; then
816				printf 'Disabling NLS...\n\n'
817				nls=0
818			else
819				printf 'Forcing NLS...\n\n'
820			fi
821		else
822
823			printf 'gencat works.\n\n'
824
825			if [ "$HOSTCC" != "$CC" ]; then
826				printf 'Cross-compile detected.\n\n'
827				printf 'WARNING: Catalog files generated with gencat may not be portable\n'
828				printf '         across different architectures.\n\n'
829			fi
830
831			if [ -z "$NLSPATH" ]; then
832				NLSPATH="/usr/share/locale/%L/%N"
833			fi
834
835			install_locales_prereqs=" install_locales"
836			uninstall_locales_prereqs=" uninstall_locales"
837
838		fi
839
840	fi
841
842	set -e
843
844else
845	install_locales_prereqs=""
846	uninstall_locales_prereqs=""
847	all_locales=0
848fi
849
850if [ "$nls" -ne 0 ] && [ "$all_locales" -ne 0 ]; then
851	install_locales="\$(LOCALE_INSTALL) -l \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)"
852else
853	install_locales="\$(LOCALE_INSTALL) \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)"
854fi
855
856if [ "$hist" -eq 1 ]; then
857
858	set +e
859
860	printf 'Testing history...\n'
861
862	flags="-DBC_ENABLE_HISTORY=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
863	flags="$flags -DBC_ENABLE_NLS=$nls -DBC_ENABLE_LIBRARY=0"
864	flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/"
865	flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
866
867	"$CC" $CPPFLAGS $CFLAGS $flags -c "src/history.c" -o "$scriptdir/history.o" > /dev/null 2>&1
868
869	err="$?"
870
871	rm -rf "$scriptdir/history.o"
872
873	# If this errors, it is probably because of building on Windows,
874	# and history is not supported on Windows, so disable it.
875	if [ "$err" -ne 0 ]; then
876		printf 'History does not work.\n'
877		if [ $force -eq 0 ]; then
878			printf 'Disabling history...\n\n'
879			hist=0
880		else
881			printf 'Forcing history...\n\n'
882		fi
883	else
884		printf 'History works.\n\n'
885	fi
886
887	set -e
888
889fi
890
891if [ "$library" -eq 1 ]; then
892	bc_lib=""
893fi
894
895if [ "$extra_math" -eq 1 ] && [ "$bc" -ne 0 ] && [ "$library" -eq 0 ]; then
896	BC_LIB2_O="\$(GEN_DIR)/lib2.o"
897else
898	BC_LIB2_O=""
899fi
900
901GEN="strgen"
902GEN_EXEC_TARGET="\$(HOSTCC) \$(HOSTCFLAGS) -o \$(GEN_EXEC) \$(GEN_C)"
903CLEAN_PREREQS=" clean_gen"
904
905if [ -z "${GEN_HOST+set}" ]; then
906	GEN_HOST=1
907else
908	if [ "$GEN_HOST" -eq 0 ]; then
909		GEN="strgen.sh"
910		GEN_EXEC_TARGET="@printf 'Do not need to build gen/strgen.c\\\\n'"
911		CLEAN_PREREQS=""
912	fi
913fi
914
915manpage_args=""
916
917if [ "$extra_math" -eq 0 ]; then
918	manpage_args="E"
919fi
920
921if [ "$hist" -eq 0 ]; then
922	manpage_args="${manpage_args}H"
923fi
924
925if [ "$nls" -eq 0 ]; then
926	manpage_args="${manpage_args}N"
927fi
928
929if [ "$prompt" -eq 0 ]; then
930	manpage_args="${manpage_args}P"
931fi
932
933if [ "$manpage_args" = "" ]; then
934	manpage_args="A"
935fi
936
937unneeded=""
938
939if [ "$hist" -eq 0 ]; then
940	unneeded="$unneeded history.c"
941fi
942
943if [ "$bc" -eq 0 ]; then
944	unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
945fi
946
947if [ "$dc" -eq 0 ]; then
948	unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
949fi
950
951if [ "$extra_math" -eq 0 ]; then
952	unneeded="$unneeded rand.c"
953fi
954
955if [ "$library" -ne 0 ]; then
956	unneeded="$unneeded args.c opt.c read.c file.c main.c"
957	unneeded="$unneeded lang.c lex.c parse.c program.c"
958	unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
959	unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
960else
961	unneeded="$unneeded library.c"
962fi
963
964# Print out the values; this is for debugging.
965if [ "$bc" -ne 0 ]; then
966	printf 'Building bc\n'
967else
968	printf 'Not building bc\n'
969fi
970if [ "$dc" -ne 0 ]; then
971	printf 'Building dc\n'
972else
973	printf 'Not building dc\n'
974fi
975printf '\n'
976printf 'BC_ENABLE_LIBRARY=%s\n\n' "$library"
977printf 'BC_ENABLE_HISTORY=%s\n' "$hist"
978printf 'BC_ENABLE_EXTRA_MATH=%s\n' "$extra_math"
979printf 'BC_ENABLE_NLS=%s\n' "$nls"
980printf 'BC_ENABLE_PROMPT=%s\n' "$prompt"
981printf '\n'
982printf 'BC_NUM_KARATSUBA_LEN=%s\n' "$karatsuba_len"
983printf '\n'
984printf 'CC=%s\n' "$CC"
985printf 'CFLAGS=%s\n' "$CFLAGS"
986printf 'HOSTCC=%s\n' "$HOSTCC"
987printf 'HOSTCFLAGS=%s\n' "$HOSTCFLAGS"
988printf 'CPPFLAGS=%s\n' "$CPPFLAGS"
989printf 'LDFLAGS=%s\n' "$LDFLAGS"
990printf 'PREFIX=%s\n' "$PREFIX"
991printf 'BINDIR=%s\n' "$BINDIR"
992printf 'INCLUDEDIR=%s\n' "$INCLUDEDIR"
993printf 'LIBDIR=%s\n' "$LIBDIR"
994printf 'DATAROOTDIR=%s\n' "$DATAROOTDIR"
995printf 'DATADIR=%s\n' "$DATADIR"
996printf 'MANDIR=%s\n' "$MANDIR"
997printf 'MAN1DIR=%s\n' "$MAN1DIR"
998printf 'MAN3DIR=%s\n' "$MAN3DIR"
999printf 'NLSPATH=%s\n' "$NLSPATH"
1000printf 'EXECSUFFIX=%s\n' "$EXECSUFFIX"
1001printf 'EXECPREFIX=%s\n' "$EXECPREFIX"
1002printf 'DESTDIR=%s\n' "$DESTDIR"
1003printf 'LONG_BIT=%s\n' "$LONG_BIT"
1004printf 'GEN_HOST=%s\n' "$GEN_HOST"
1005printf 'GEN_EMU=%s\n' "$GEN_EMU"
1006
1007contents=$(cat "$scriptdir/Makefile.in")
1008
1009needle="WARNING"
1010replacement='*** WARNING: Autogenerated from Makefile.in. DO NOT MODIFY ***'
1011
1012contents=$(replace "$contents" "$needle" "$replacement")
1013
1014if [ "$unneeded" = "" ]; then
1015	contents=$(gen_file_list "$contents" "library.c")
1016else
1017	contents=$(gen_file_list "$contents" $unneeded)
1018fi
1019
1020contents=$(replace "$contents" "BC_ENABLED" "$bc")
1021contents=$(replace "$contents" "DC_ENABLED" "$dc")
1022contents=$(replace "$contents" "LINK" "$link")
1023
1024contents=$(replace "$contents" "LIBRARY" "$library")
1025contents=$(replace "$contents" "HISTORY" "$hist")
1026contents=$(replace "$contents" "EXTRA_MATH" "$extra_math")
1027contents=$(replace "$contents" "NLS" "$nls")
1028contents=$(replace "$contents" "PROMPT" "$prompt")
1029contents=$(replace "$contents" "BC_LIB_O" "$bc_lib")
1030contents=$(replace "$contents" "BC_HELP_O" "$bc_help")
1031contents=$(replace "$contents" "DC_HELP_O" "$dc_help")
1032contents=$(replace "$contents" "BC_LIB2_O" "$BC_LIB2_O")
1033contents=$(replace "$contents" "KARATSUBA_LEN" "$karatsuba_len")
1034
1035contents=$(replace "$contents" "NLSPATH" "$NLSPATH")
1036contents=$(replace "$contents" "DESTDIR" "$destdir")
1037contents=$(replace "$contents" "EXECSUFFIX" "$EXECSUFFIX")
1038contents=$(replace "$contents" "EXECPREFIX" "$EXECPREFIX")
1039contents=$(replace "$contents" "BINDIR" "$BINDIR")
1040contents=$(replace "$contents" "INCLUDEDIR" "$INCLUDEDIR")
1041contents=$(replace "$contents" "LIBDIR" "$LIBDIR")
1042contents=$(replace "$contents" "MAN1DIR" "$MAN1DIR")
1043contents=$(replace "$contents" "MAN3DIR" "$MAN3DIR")
1044contents=$(replace "$contents" "CFLAGS" "$CFLAGS")
1045contents=$(replace "$contents" "HOSTCFLAGS" "$HOSTCFLAGS")
1046contents=$(replace "$contents" "CPPFLAGS" "$CPPFLAGS")
1047contents=$(replace "$contents" "LDFLAGS" "$LDFLAGS")
1048contents=$(replace "$contents" "CC" "$CC")
1049contents=$(replace "$contents" "HOSTCC" "$HOSTCC")
1050contents=$(replace "$contents" "COVERAGE_OUTPUT" "$COVERAGE_OUTPUT")
1051contents=$(replace "$contents" "COVERAGE_PREREQS" "$COVERAGE_PREREQS")
1052contents=$(replace "$contents" "INSTALL_PREREQS" "$install_prereqs")
1053contents=$(replace "$contents" "INSTALL_MAN_PREREQS" "$install_man_prereqs")
1054contents=$(replace "$contents" "INSTALL_LOCALES" "$install_locales")
1055contents=$(replace "$contents" "INSTALL_LOCALES_PREREQS" "$install_locales_prereqs")
1056contents=$(replace "$contents" "UNINSTALL_MAN_PREREQS" "$uninstall_man_prereqs")
1057contents=$(replace "$contents" "UNINSTALL_PREREQS" "$uninstall_prereqs")
1058contents=$(replace "$contents" "UNINSTALL_LOCALES_PREREQS" "$uninstall_locales_prereqs")
1059
1060contents=$(replace "$contents" "ALL_PREREQ" "$ALL_PREREQ")
1061
1062contents=$(replace "$contents" "EXECUTABLES" "$executables")
1063contents=$(replace "$contents" "MAIN_EXEC" "$main_exec")
1064contents=$(replace "$contents" "EXEC" "$executable")
1065contents=$(replace "$contents" "TESTS" "$tests")
1066
1067contents=$(replace "$contents" "BC_TEST" "$bc_test")
1068contents=$(replace "$contents" "BC_TIME_TEST" "$bc_time_test")
1069
1070contents=$(replace "$contents" "DC_TEST" "$dc_test")
1071contents=$(replace "$contents" "DC_TIME_TEST" "$dc_time_test")
1072
1073contents=$(replace "$contents" "VG_BC_TEST" "$vg_bc_test")
1074contents=$(replace "$contents" "VG_DC_TEST" "$vg_dc_test")
1075
1076contents=$(replace "$contents" "TIMECONST" "$timeconst")
1077
1078contents=$(replace "$contents" "KARATSUBA" "$karatsuba")
1079contents=$(replace "$contents" "KARATSUBA_TEST" "$karatsuba_test")
1080
1081contents=$(replace "$contents" "LONG_BIT" "$LONG_BIT")
1082contents=$(replace "$contents" "LONG_BIT_DEFINE" "$LONG_BIT_DEFINE")
1083
1084contents=$(replace "$contents" "GEN" "$GEN")
1085contents=$(replace "$contents" "GEN_EXEC_TARGET" "$GEN_EXEC_TARGET")
1086contents=$(replace "$contents" "CLEAN_PREREQS" "$CLEAN_PREREQS")
1087contents=$(replace "$contents" "GEN_EMU" "$GEN_EMU")
1088
1089printf '%s\n' "$contents" > "$scriptdir/Makefile"
1090
1091cd "$scriptdir"
1092
1093cp -f manuals/bc/$manpage_args.1.md manuals/bc.1.md
1094cp -f manuals/bc/$manpage_args.1 manuals/bc.1
1095cp -f manuals/dc/$manpage_args.1.md manuals/dc.1.md
1096cp -f manuals/dc/$manpage_args.1 manuals/dc.1
1097
1098make clean > /dev/null
1099