contrib/bc: merge version 5.2.1 from vendor branch

Merge commit 'e63540eed295749528548c2e3a90f5a6e57275c8'
This commit is contained in:
Stefan Eßer 2021-11-30 18:40:32 +01:00
commit 10041e99a0
94 changed files with 1244 additions and 364 deletions

View File

@ -29,6 +29,15 @@
#
.POSIX:
ROOTDIR = %%ROOTDIR%%
INCDIR = $(ROOTDIR)/include
SRCDIR = $(ROOTDIR)/src
TESTSDIR = $(ROOTDIR)/tests
SCRIPTSDIR = $(ROOTDIR)/scripts
GENDIR = $(ROOTDIR)/gen
BUILDDIR = %%BUILDDIR%%
SRC = %%SRC%%
OBJ = %%OBJ%%
GCDA = %%GCDA%%
@ -39,46 +48,45 @@ BC_ENABLED = %%BC_ENABLED%%
DC_ENABLED_NAME = DC_ENABLED
DC_ENABLED = %%DC_ENABLED%%
HEADERS = include/args.h include/file.h include/lang.h include/lex.h include/num.h include/opt.h include/parse.h include/program.h include/read.h include/status.h include/vector.h include/vm.h
BC_HEADERS = include/bc.h
DC_HEADERS = include/dc.h
HISTORY_HEADERS = include/history.h
EXTRA_MATH_HEADERS = include/rand.h
LIBRARY_HEADERS = include/bcl.h include/library.h
HEADERS = $(INCDIR)/args.h $(INCDIR)/file.h $(INCDIR)/lang.h $(INCDIR)/lex.h $(INCDIR)/num.h $(INCDIR)/opt.h $(INCDIR)/parse.h $(INCDIR)/program.h $(INCDIR)/read.h $(INCDIR)/status.h $(INCDIR)/vector.h $(INCDIR)/vm.h
BC_HEADERS = $(INCDIR)/bc.h
DC_HEADERS = $(INCDIR)/dc.h
HISTORY_HEADERS = $(INCDIR)/history.h
EXTRA_MATH_HEADERS = $(INCDIR)/rand.h
LIBRARY_HEADERS = $(INCDIR)/bcl.h $(INCDIR)/library.h
GEN_DIR = gen
GEN = %%GEN%%
GEN_EXEC = $(GEN_DIR)/$(GEN)
GEN_C = $(GEN_DIR)/$(GEN).c
GEN_C = $(GENDIR)/$(GEN).c
GEN_EMU = %%GEN_EMU%%
BC_LIB = $(GEN_DIR)/lib.bc
BC_LIB = $(GENDIR)/lib.bc
BC_LIB_C = $(GEN_DIR)/lib.c
BC_LIB_O = %%BC_LIB_O%%
BC_LIB_GCDA = $(GEN_DIR)/lib.gcda
BC_LIB_GCNO = $(GEN_DIR)/lib.gcno
BC_LIB2 = $(GEN_DIR)/lib2.bc
BC_LIB2 = $(GENDIR)/lib2.bc
BC_LIB2_C = $(GEN_DIR)/lib2.c
BC_LIB2_O = %%BC_LIB2_O%%
BC_LIB2_GCDA = $(GEN_DIR)/lib2.gcda
BC_LIB2_GCNO = $(GEN_DIR)/lib2.gcno
BC_HELP = $(GEN_DIR)/bc_help.txt
BC_HELP = $(GENDIR)/bc_help.txt
BC_HELP_C = $(GEN_DIR)/bc_help.c
BC_HELP_O = %%BC_HELP_O%%
BC_HELP_GCDA = $(GEN_DIR)/bc_help.gcda
BC_HELP_GCNO = $(GEN_DIR)/bc_help.gcno
DC_HELP = $(GEN_DIR)/dc_help.txt
DC_HELP = $(GENDIR)/dc_help.txt
DC_HELP_C = $(GEN_DIR)/dc_help.c
DC_HELP_O = %%DC_HELP_O%%
DC_HELP_GCDA = $(GEN_DIR)/dc_help.gcda
DC_HELP_GCNO = $(GEN_DIR)/dc_help.gcno
BIN = bin
LOCALES = locales
EXEC_SUFFIX = %%EXECSUFFIX%%
EXEC_PREFIX = %%EXECPREFIX%%
@ -97,7 +105,7 @@ LIB_NAME = $(LIB).a
LIBBC = $(BIN)/$(LIB_NAME)
BCL = bcl
BCL_TEST = $(BIN)/$(BCL)
BCL_TEST_C = tests/$(BCL).c
BCL_TEST_C = $(TESTSDIR)/$(BCL).c
MANUALS = manuals
BC_MANPAGE_NAME = $(EXEC_PREFIX)$(BC)$(EXEC_SUFFIX).1
@ -112,9 +120,13 @@ BCL_MD = $(BCL_MANPAGE).md
MANPAGE_INSTALL_ARGS = -Dm644
BINARY_INSTALL_ARGS = -Dm755
PC_INSTALL_ARGS = $(MANPAGE_INSTALL_ARGS)
BCL_PC = $(BCL).pc
PC_PATH = %%PC_PATH%%
BCL_HEADER_NAME = bcl.h
BCL_HEADER = include/$(BCL_HEADER_NAME)
BCL_HEADER = $(INCDIR)/$(BCL_HEADER_NAME)
%%DESTDIR%%
BINDIR = %%BINDIR%%
@ -146,6 +158,8 @@ BC_DEFAULT_TTY_MODE = %%BC_DEFAULT_TTY_MODE%%
DC_DEFAULT_TTY_MODE = %%DC_DEFAULT_TTY_MODE%%
BC_DEFAULT_PROMPT = %%BC_DEFAULT_PROMPT%%
DC_DEFAULT_PROMPT = %%DC_DEFAULT_PROMPT%%
BC_DEFAULT_EXPR_EXIT = %%BC_DEFAULT_EXPR_EXIT%%
DC_DEFAULT_EXPR_EXIT = %%DC_DEFAULT_EXPR_EXIT%%
RM = rm
MKDIR = mkdir
@ -158,13 +172,13 @@ MINISTAT_EXEC = $(SCRIPTS)/$(MINISTAT)
BITFUNCGEN = bitfuncgen
BITFUNCGEN_EXEC = $(SCRIPTS)/$(BITFUNCGEN)
INSTALL = $(SCRIPTS)/exec-install.sh
SAFE_INSTALL = $(SCRIPTS)/safe-install.sh
LINK = $(SCRIPTS)/link.sh
MANPAGE = $(SCRIPTS)/manpage.sh
KARATSUBA = $(SCRIPTS)/karatsuba.py
LOCALE_INSTALL = $(SCRIPTS)/locale_install.sh
LOCALE_UNINSTALL = $(SCRIPTS)/locale_uninstall.sh
INSTALL = $(SCRIPTSDIR)/exec-install.sh
SAFE_INSTALL = $(SCRIPTSDIR)/safe-install.sh
LINK = $(SCRIPTSDIR)/link.sh
MANPAGE = $(SCRIPTSDIR)/manpage.sh
KARATSUBA = $(SCRIPTSDIR)/karatsuba.py
LOCALE_INSTALL = $(SCRIPTSDIR)/locale_install.sh
LOCALE_UNINSTALL = $(SCRIPTSDIR)/locale_uninstall.sh
VALGRIND_ARGS = --error-exitcode=100 --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all
@ -176,14 +190,16 @@ BC_DEFS0 = -DBC_DEFAULT_BANNER=$(BC_DEFAULT_BANNER)
BC_DEFS1 = -DBC_DEFAULT_SIGINT_RESET=$(BC_DEFAULT_SIGINT_RESET)
BC_DEFS2 = -DBC_DEFAULT_TTY_MODE=$(BC_DEFAULT_TTY_MODE)
BC_DEFS3 = -DBC_DEFAULT_PROMPT=$(BC_DEFAULT_PROMPT)
BC_DEFS = $(BC_DEFS0) $(BC_DEFS1) $(BC_DEFS2) $(BC_DEFS3)
BC_DEFS4 = -DBC_DEFAULT_EXPR_EXIT=$(BC_DEFAULT_EXPR_EXIT)
BC_DEFS = $(BC_DEFS0) $(BC_DEFS1) $(BC_DEFS2) $(BC_DEFS3) $(BC_DEFS4)
DC_DEFS1 = -DDC_DEFAULT_SIGINT_RESET=$(DC_DEFAULT_SIGINT_RESET)
DC_DEFS2 = -DDC_DEFAULT_TTY_MODE=$(DC_DEFAULT_TTY_MODE)
DC_DEFS3 = -DDC_DEFAULT_PROMPT=$(DC_DEFAULT_PROMPT)
DC_DEFS = $(DC_DEFS1) $(DC_DEFS2) $(DC_DEFS3)
DC_DEFS4 = -DDC_DEFAULT_EXPR_EXIT=$(DC_DEFAULT_EXPR_EXIT)
DC_DEFS = $(DC_DEFS1) $(DC_DEFS2) $(DC_DEFS3) $(DC_DEFS4)
CPPFLAGS1 = -D$(BC_ENABLED_NAME)=$(BC_ENABLED) -D$(DC_ENABLED_NAME)=$(DC_ENABLED)
CPPFLAGS2 = $(CPPFLAGS1) -I./include/ -DBUILD_TYPE=$(BC_BUILD_TYPE) %%LONG_BIT_DEFINE%%
CPPFLAGS2 = $(CPPFLAGS1) -I$(INCDIR)/ -DBUILD_TYPE=$(BC_BUILD_TYPE) %%LONG_BIT_DEFINE%%
CPPFLAGS3 = $(CPPFLAGS2) -DEXECPREFIX=$(EXEC_PREFIX) -DMAINEXEC=$(MAIN_EXEC)
CPPFLAGS4 = $(CPPFLAGS3) -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 %%BSD%%
CPPFLAGS5 = $(CPPFLAGS4) -DBC_NUM_KARATSUBA_LEN=$(BC_NUM_KARATSUBA_LEN)
@ -212,7 +228,10 @@ all: %%DEFAULT_TARGET%%
%%SECOND_TARGET%%: %%SECOND_TARGET_PREREQS%%
%%SECOND_TARGET_CMD%%
$(GEN_EXEC):
$(GEN_DIR):
mkdir -p $(GEN_DIR)
$(GEN_EXEC): $(GEN_DIR)
%%GEN_EXEC_TARGET%%
$(BC_LIB_C): $(GEN_EXEC) $(BC_LIB)
@ -242,13 +261,18 @@ $(DC_HELP_O): $(DC_HELP_C)
$(BIN):
$(MKDIR) -p $(BIN)
src:
$(MKDIR) -p src
headers: %%HEADERS%%
$(MINISTAT):
$(HOSTCC) $(HOSTCFLAGS) -lm -o $(MINISTAT_EXEC) scripts/ministat.c
mkdir -p $(SCRIPTS)
$(HOSTCC) $(HOSTCFLAGS) -lm -o $(MINISTAT_EXEC) $(ROOTDIR)/scripts/ministat.c
$(BITFUNCGEN):
$(HOSTCC) $(HOSTCFLAGS) -lm -o $(BITFUNCGEN_EXEC) scripts/bitfuncgen.c
mkdir -p $(SCRIPTS)
$(HOSTCC) $(HOSTCFLAGS) -lm -o $(BITFUNCGEN_EXEC) $(ROOTDIR)/scripts/bitfuncgen.c
help:
@printf 'available targets:\n'
@ -314,18 +338,18 @@ test_bc_tests:%%BC_TESTS%%
test_bc_scripts:%%BC_SCRIPT_TESTS%%
test_bc_stdin:
@sh tests/stdin.sh bc %%BC_TEST_EXEC%%
@export BC_TEST_OUTPUT_DIR="$(BUILDDIR)/tests"; sh $(TESTSDIR)/stdin.sh bc %%BC_TEST_EXEC%%
test_bc_read:
@sh tests/read.sh bc %%BC_TEST_EXEC%%
@export BC_TEST_OUTPUT_DIR="$(BUILDDIR)/tests"; sh $(TESTSDIR)/read.sh bc %%BC_TEST_EXEC%%
test_bc_errors: test_bc_error_lines%%BC_ERROR_TESTS%%
test_bc_error_lines:
@sh tests/errors.sh bc %%BC_TEST_EXEC%%
@export BC_TEST_OUTPUT_DIR="$(BUILDDIR)/tests"; sh $(TESTSDIR)/errors.sh bc %%BC_TEST_EXEC%%
test_bc_other:
@sh tests/other.sh bc $(BC_ENABLE_EXTRA_MATH) %%BC_TEST_EXEC%%
@export BC_TEST_OUTPUT_DIR="$(BUILDDIR)/tests"; sh $(TESTSDIR)/other.sh bc $(BC_ENABLE_EXTRA_MATH) %%BC_TEST_EXEC%%
test_bc_header:
@printf '$(TEST_STARS)\n\nRunning bc tests...\n\n'
@ -338,18 +362,18 @@ test_dc_tests:%%DC_TESTS%%
test_dc_scripts:%%DC_SCRIPT_TESTS%%
test_dc_stdin:
@sh tests/stdin.sh dc %%DC_TEST_EXEC%%
@export BC_TEST_OUTPUT_DIR="$(BUILDDIR)/tests"; sh $(TESTSDIR)/stdin.sh dc %%DC_TEST_EXEC%%
test_dc_read:
@sh tests/read.sh dc %%DC_TEST_EXEC%%
@export BC_TEST_OUTPUT_DIR="$(BUILDDIR)/tests"; sh $(TESTSDIR)/read.sh dc %%DC_TEST_EXEC%%
test_dc_errors: test_dc_error_lines%%DC_ERROR_TESTS%%
test_dc_error_lines:
@sh tests/errors.sh dc %%DC_TEST_EXEC%%
@export BC_TEST_OUTPUT_DIR="$(BUILDDIR)/tests"; sh $(TESTSDIR)/errors.sh dc %%DC_TEST_EXEC%%
test_dc_other:
@sh tests/other.sh dc $(BC_ENABLE_EXTRA_MATH) %%DC_TEST_EXEC%%
@export BC_TEST_OUTPUT_DIR="$(BUILDDIR)/tests"; sh $(TESTSDIR)/other.sh dc $(BC_ENABLE_EXTRA_MATH) %%DC_TEST_EXEC%%
test_dc_header:
@printf '$(TEST_STARS)\n\nRunning dc tests...\n\n'
@ -368,107 +392,110 @@ test_bc_history_skip:
@printf 'No bc history tests to run\n'
test_bc_history0:
@sh tests/history.sh bc 0 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 0 %%BC_TEST_EXEC%%
test_bc_history1:
@sh tests/history.sh bc 1 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 1 %%BC_TEST_EXEC%%
test_bc_history2:
@sh tests/history.sh bc 2 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 2 %%BC_TEST_EXEC%%
test_bc_history3:
@sh tests/history.sh bc 3 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 3 %%BC_TEST_EXEC%%
test_bc_history4:
@sh tests/history.sh bc 4 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 4 %%BC_TEST_EXEC%%
test_bc_history5:
@sh tests/history.sh bc 5 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 5 %%BC_TEST_EXEC%%
test_bc_history6:
@sh tests/history.sh bc 6 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 6 %%BC_TEST_EXEC%%
test_bc_history7:
@sh tests/history.sh bc 7 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 7 %%BC_TEST_EXEC%%
test_bc_history8:
@sh tests/history.sh bc 8 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 8 %%BC_TEST_EXEC%%
test_bc_history9:
@sh tests/history.sh bc 9 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 9 %%BC_TEST_EXEC%%
test_bc_history10:
@sh tests/history.sh bc 10 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 10 %%BC_TEST_EXEC%%
test_bc_history11:
@sh tests/history.sh bc 11 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 11 %%BC_TEST_EXEC%%
test_bc_history12:
@sh tests/history.sh bc 12 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 12 %%BC_TEST_EXEC%%
test_bc_history13:
@sh tests/history.sh bc 13 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 13 %%BC_TEST_EXEC%%
test_bc_history14:
@sh tests/history.sh bc 14 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 14 %%BC_TEST_EXEC%%
test_bc_history15:
@sh tests/history.sh bc 15 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 15 %%BC_TEST_EXEC%%
test_bc_history16:
@sh tests/history.sh bc 16 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 16 %%BC_TEST_EXEC%%
test_bc_history17:
@sh tests/history.sh bc 17 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 17 %%BC_TEST_EXEC%%
test_bc_history18:
@sh tests/history.sh bc 18 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 18 %%BC_TEST_EXEC%%
test_bc_history19:
@sh tests/history.sh bc 19 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 19 %%BC_TEST_EXEC%%
test_bc_history20:
@sh tests/history.sh bc 20 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 20 %%BC_TEST_EXEC%%
test_bc_history21:
@sh tests/history.sh bc 21 %%BC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh bc 21 %%BC_TEST_EXEC%%
test_dc_history:%%DC_HISTORY_TEST_PREREQS%%
test_dc_history_all: test_dc_history0 test_dc_history1 test_dc_history2 test_dc_history3 test_dc_history4 test_dc_history5 test_dc_history6 test_dc_history7 test_dc_history8 test_dc_history9
test_dc_history_all: test_dc_history0 test_dc_history1 test_dc_history2 test_dc_history3 test_dc_history4 test_dc_history5 test_dc_history6 test_dc_history7 test_dc_history8 test_dc_history9 test_dc_history10
test_dc_history_skip:
@printf 'No dc history tests to run\n'
test_dc_history0:
@sh tests/history.sh dc 0 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 0 %%DC_TEST_EXEC%%
test_dc_history1:
@sh tests/history.sh dc 1 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 1 %%DC_TEST_EXEC%%
test_dc_history2:
@sh tests/history.sh dc 2 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 2 %%DC_TEST_EXEC%%
test_dc_history3:
@sh tests/history.sh dc 3 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 3 %%DC_TEST_EXEC%%
test_dc_history4:
@sh tests/history.sh dc 4 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 4 %%DC_TEST_EXEC%%
test_dc_history5:
@sh tests/history.sh dc 5 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 5 %%DC_TEST_EXEC%%
test_dc_history6:
@sh tests/history.sh dc 6 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 6 %%DC_TEST_EXEC%%
test_dc_history7:
@sh tests/history.sh dc 7 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 7 %%DC_TEST_EXEC%%
test_dc_history8:
@sh tests/history.sh dc 8 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 8 %%DC_TEST_EXEC%%
test_dc_history9:
@sh tests/history.sh dc 9 %%DC_TEST_EXEC%%
@sh $(TESTSDIR)/history.sh dc 9 %%DC_TEST_EXEC%%
test_dc_history10:
@sh $(TESTSDIR)/history.sh dc 10 %%DC_TEST_EXEC%%
test_history_header:
@printf '$(TEST_STARS)\n\nRunning history tests...\n\n'
@ -505,18 +532,17 @@ clean:%%CLEAN_PREREQS%%
@$(RM) -f $(BC_EXEC)
@$(RM) -f $(DC_EXEC)
@$(RM) -fr $(BIN)
@$(RM) -f $(LOCALES)/*.cat
@$(RM) -f $(BC_LIB_C) $(BC_LIB_O)
@$(RM) -f $(BC_LIB2_C) $(BC_LIB2_O)
@$(RM) -f $(BC_HELP_C) $(BC_HELP_O)
@$(RM) -f $(DC_HELP_C) $(DC_HELP_O)
@$(RM) -fr Debug/ Release/
@$(RM) -fr vs/bin/ vs/lib/
clean_benchmarks:
@printf 'Cleaning benchmarks...\n'
@$(RM) -f $(MINISTAT_EXEC)
@$(RM) -f benchmarks/bc/*.txt
@$(RM) -f benchmarks/dc/*.txt
@$(RM) -f $(ROOTDIR)/benchmarks/bc/*.txt
@$(RM) -f $(ROOTDIR)/benchmarks/dc/*.txt
clean_config: clean clean_benchmarks
@printf 'Cleaning config...\n'
@ -544,19 +570,19 @@ clean_tests: clean clean_config clean_coverage
@printf 'Cleaning test files...\n'
@$(RM) -fr $(BC_TEST_OUTPUTS) $(DC_TEST_OUTPUTS)
@$(RM) -fr $(BC_FUZZ_OUTPUTS) $(DC_FUZZ_OUTPUTS)
@$(RM) -f tests/bc/parse.txt tests/bc/parse_results.txt
@$(RM) -f tests/bc/print.txt tests/bc/print_results.txt
@$(RM) -f tests/bc/bessel.txt tests/bc/bessel_results.txt
@$(RM) -f tests/bc/strings2.txt tests/bc/strings2_results.txt
@$(RM) -f tests/bc/scripts/bessel.txt
@$(RM) -f tests/bc/scripts/parse.txt
@$(RM) -f tests/bc/scripts/print.txt
@$(RM) -f tests/bc/scripts/add.txt
@$(RM) -f tests/bc/scripts/divide.txt
@$(RM) -f tests/bc/scripts/multiply.txt
@$(RM) -f tests/bc/scripts/subtract.txt
@$(RM) -f tests/bc/scripts/strings2.txt
@$(RM) -f tests/dc/scripts/prime.txt
@$(RM) -f $(TESTSDIR)/bc/parse.txt $(TESTSDIR)/bc/parse_results.txt
@$(RM) -f $(TESTSDIR)/bc/print.txt $(TESTSDIR)/bc/print_results.txt
@$(RM) -f $(TESTSDIR)/bc/bessel.txt $(TESTSDIR)/bc/bessel_results.txt
@$(RM) -f $(TESTSDIR)/bc/strings2.txt $(TESTSDIR)/bc/strings2_results.txt
@$(RM) -f $(TESTSDIR)/bc/scripts/bessel.txt
@$(RM) -f $(TESTSDIR)/bc/scripts/parse.txt
@$(RM) -f $(TESTSDIR)/bc/scripts/print.txt
@$(RM) -f $(TESTSDIR)/bc/scripts/add.txt
@$(RM) -f $(TESTSDIR)/bc/scripts/divide.txt
@$(RM) -f $(TESTSDIR)/bc/scripts/multiply.txt
@$(RM) -f $(TESTSDIR)/bc/scripts/subtract.txt
@$(RM) -f $(TESTSDIR)/bc/scripts/strings2.txt
@$(RM) -f $(TESTSDIR)/dc/scripts/prime.txt
@$(RM) -f .log_*.txt
@$(RM) -f .math.txt .results.txt .ops.txt
@$(RM) -f .test.txt
@ -581,10 +607,11 @@ install_bcl_header:
$(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(BCL_HEADER) $(DESTDIR)$(INCLUDEDIR)/$(BCL_HEADER_NAME)
install_execs:
$(INSTALL) $(DESTDIR)$(BINDIR) "$(EXEC_SUFFIX)"
$(INSTALL) $(DESTDIR)$(BINDIR) "$(EXEC_SUFFIX)" "$(BUILDDIR)/bin"
install_library:
install_library: install_bcl_header
$(SAFE_INSTALL) $(BINARY_INSTALL_ARGS) $(LIBBC) $(DESTDIR)$(LIBDIR)/$(LIB_NAME)
%%PKG_CONFIG_INSTALL%%
install:%%INSTALL_LOCALES_PREREQS%%%%INSTALL_MAN_PREREQS%%%%INSTALL_PREREQS%%
@ -603,8 +630,9 @@ uninstall_dc_manpage:
uninstall_dc:
$(RM) -f $(DESTDIR)$(BINDIR)/$(EXEC_PREFIX)$(DC)$(EXEC_SUFFIX)
uninstall_library:
uninstall_library: uninstall_bcl_header
$(RM) -f $(DESTDIR)$(LIBDIR)/$(LIB_NAME)
%%PKG_CONFIG_UNINSTALL%%
uninstall_bcl_header:
$(RM) -f $(DESTDIR)$(INCLUDEDIR)/$(BCL_HEADER_NAME)

View File

@ -1,5 +1,25 @@
# News
## 5.2.1
This is a production release that fixes two parse bugs when in POSIX standard
mode. One of these bugs was due to a quirk of the POSIX grammar, and the other
was because `bc` was too strict.
## 5.2.0
This is a production release that adds a new feature, fixes some bugs, and adds
out-of-source builds and a `pkg-config` file for `bcl`.
The new feature is the ability to turn off exiting on expressions. It is also
possible to set the default using `configure.sh`. This behavior used to exist
with the `BC_EXPR_EXIT` environment variable, which is now used again.
Bugs fixed include:
* Some possible race conditions with error handling.
* Install and uninstall targets for `bcl` did not work.
## 5.1.1
This is a production release that completes a bug fix from `5.1.0`. The bug

View File

@ -58,8 +58,8 @@ system.
This `bc` should build unmodified on any POSIX-compliant system or on Windows
starting with Windows 10 (though earlier versions may work).
For more complex build requirements than the ones below, see the
[build manual][5].
For more complex build requirements than the ones below, see the [build
manual][5].
### Windows
@ -76,38 +76,45 @@ support) disabled, with both calculators built.
#### `bc`
To build `bc`, you can open the `bc.sln` file in Visual Studio, select the
To build `bc`, you can open the `vs/bc.sln` file in Visual Studio, select the
configuration, and build.
You can also build using MSBuild with the following from the root directory:
```
msbuild -property:Configuration=<config> bc.sln
msbuild -property:Configuration=<config> vs/bc.sln
```
where `<config>` is either one of `Debug` or `Release`.
On Windows, the calculators are built as `vs/bin/<platform>/<config>/bc.exe` and
`vs/bin/<Platform>/<Config>/dc.exe`, where `<platform>` can be either `Win32` or
`x64`, and `<config>` can be `Debug` or `Release`.
**Note**: On Windows, `dc.exe` is just copied from `bc.exe`; it is not linked.
Patches are welcome for a way to do that.
#### `bcl` (Library)
To build the library, you can open the `bcl.sln` file in Visual Studio, select
the configuration, and build.
To build the library, you can open the `vs/bcl.sln` file in Visual Studio,
select the configuration, and build.
You can also build using MSBuild with the following from the root directory:
```
msbuild -property:Configuration=<config> bcl.sln
msbuild -property:Configuration=<config> vs/bcl.sln
```
where `<config>` is either one of `Debug` or `Release`.
where `<config>` is either one of `Debug`, `ReleaseMD`, or `ReleaseMT`.
On Windows, the library is built as `vs/lib/<platform>/<config>/bcl.lib`, where
`<platform>` can be either `Win32` or `x64`, and `<config>` can be `Debug`,
`ReleaseMD`, or `ReleaseMT`.
### POSIX-Compatible Systems
On POSIX-compatible systems, `bc` is built as `bin/bc` and `dc` is built as
`bin/dc` by default. On Windows, they are built as `Release/bc/bc.exe` and
`Release/bc/dc.exe`.
**Note**: On Windows, `dc.exe` is just copied from `bc.exe`; it is not linked.
Patches are welcome for a way to do that.
`bin/dc` by default.
#### Default
@ -177,6 +184,24 @@ The library is built as `bin/libbcl.a` on POSIX-compatible systems or as
#### Package and Distro Maintainers
This section is for package and distro maintainers.
##### Out-of-Source Builds
Out-of-source builds are supported; just call `configure.sh` from the directory
where the actual build will happen.
For example, if the source is in `bc`, the build should happen in `build`, then
call `configure.sh` and `make` like so:
```
../bc/configure.sh
make
```
***WARNING***: The path to `configure.sh` from the build directory must not have
spaces because `make` does not support target names with spaces.
##### Recommended Compiler
When I ran benchmarks with my `bc` compiled under `clang`, it performed much
@ -373,16 +398,12 @@ Files:
.gitignore The git ignore file (maintainer use only).
.gitattributes The git attributes file (maintainer use only).
bc.sln The Visual Studio solution file for bc.
bc.vcxproj The Visual Studio project file for bc.
bc.vcxproj.filters The Visual Studio filters file for bc.
bcl.sln The Visual Studio solution file for bcl.
bcl.vcxproj The Visual Studio project file for bcl.
bcl.vcxproj.filters The Visual Studio filters file for bcl.
bcl.pc.in A template pkg-config file for bcl.
configure A symlink to configure.sh to make packaging easier.
configure.sh The configure script.
LICENSE.md A Markdown form of the BSD 2-clause License.
Makefile.in The Makefile template.
NEWS.md The changelog.
NOTICE.md List of contributors and copyright owners.
RELEASE.md A checklist for making a release (maintainer use only).
@ -395,6 +416,7 @@ Folders:
src All source code.
scripts A bunch of shell scripts to help with development and building.
tests All tests.
vs Files needed for the build on Windows.
[1]: https://www.gnu.org/software/bc/
[4]: ./LICENSE.md

8
contrib/bc/bcl.pc.in Normal file
View File

@ -0,0 +1,8 @@
includedir=%%INCLUDEDIR%%
libdir=%%LIBDIR%%
Name: bcl
Description: Implemention of arbitrary-precision math from the bc calculator.
Version: %%VERSION%%
Cflags: -I${includedir}
Libs: -L${libdir} -lbcl

View File

@ -31,9 +31,9 @@ script="$0"
scriptdir=$(dirname "$script")
script=$(basename "$script")
. "$scriptdir/scripts/functions.sh"
builddir=$(pwd)
cd "$scriptdir"
. "$scriptdir/scripts/functions.sh"
# Simply prints the help message and quits based on the argument.
# @param val The value to pass to exit. Must be an integer.
@ -52,13 +52,15 @@ usage() {
printf 'usage:\n'
printf ' %s -h\n' "$script"
printf ' %s --help\n' "$script"
printf ' %s [-a|-bD|-dB|-c] [-CEfgGHlmMNPtTvz] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\n' "$script"
printf ' %s [-a|-bD|-dB|-c] [-CEfgGHlmMNtTvz] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\\\n' "$script"
printf ' [-s SETTING] [-S SETTING]\n'
printf ' %s \\\n' "$script"
printf ' [--library|--bc-only --disable-dc|--dc-only --disable-bc|--coverage] \\\n'
printf ' [--force --debug --disable-extra-math --disable-generated-tests] \\\n'
printf ' [--disable-history --disable-man-pages --disable-nls --disable-strip] \\\n'
printf ' [--install-all-locales] [--opt=OPT_LEVEL] \\\n'
printf ' [--karatsuba-len=KARATSUBA_LEN] \\\n'
printf ' [--set-default-on=SETTING] [--set-default-off=SETTING] \\\n'
printf ' [--prefix=PREFIX] [--bindir=BINDIR] [--datarootdir=DATAROOTDIR] \\\n'
printf ' [--datadir=DATADIR] [--mandir=MANDIR] [--man1dir=MAN1DIR] \\\n'
printf '\n'
@ -205,6 +207,9 @@ usage() {
printf ' path (or contain one). This is treated the same as the POSIX\n'
printf ' definition of $NLSPATH (see POSIX environment variables for\n'
printf ' more information). Default is "/usr/share/locale/%%L/%%N".\n'
printf ' PC_PATH The location to install pkg-config files to. Must be an\n'
printf ' path or contain one. Default is the first path given by the\n'
printf ' output of `pkg-config --variable=pc_path pkg-config`.\n'
printf ' EXECSUFFIX The suffix to append to the executable names, used to not\n'
printf ' interfere with other installed bc executables. Default is "".\n'
printf ' EXECPREFIX The prefix to append to the executable names, used to not\n'
@ -290,6 +295,18 @@ usage() {
printf '| | for dc should be on | | |\n'
printf '| | in tty mode. | | |\n'
printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
printf '| bc.expr_exit | Whether to exit bc | 1 | BC_EXPR_EXIT |\n'
printf '| | if an expression or | | |\n'
printf '| | expression file is | | |\n'
printf '| | given with the -e or | | |\n'
printf '| | -f options. | | |\n'
printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
printf '| dc.expr_exit | Whether to exit dc | 1 | DC_EXPR_EXIT |\n'
printf '| | if an expression or | | |\n'
printf '| | expression file is | | |\n'
printf '| | given with the -e or | | |\n'
printf '| | -f options. | | |\n'
printf '| --------------- | -------------------- | ------------ | -------------------- |\n'
printf '\n'
printf 'These settings are not meant to be changed on a whim. They are meant to ensure\n'
printf 'that this bc and dc will conform to the expectations of the user on each\n'
@ -374,19 +391,34 @@ replace() {
# the arguments are all assumed to be source files that should *not* be built.
find_src_files() {
_find_src_files_args=""
if [ "$#" -ge 1 ] && [ "$1" != "" ]; then
while [ "$#" -ge 1 ]; do
_find_src_files_a="${1## }"
shift
_find_src_files_args="$_find_src_files_args ! -path src/${_find_src_files_a}"
_find_src_files_args=$(printf '%s\n%s/src/%s\n' "$_find_src_files_args" "$scriptdir" "${_find_src_files_a}")
done
else
_find_src_files_args="-print"
fi
printf '%s\n' $(find src/ -depth -name "*.c" $_find_src_files_args)
_find_src_files_files=$(find "$scriptdir/src/" -depth -name "*.c" -print)
_find_src_files_result=""
for _find_src_files_f in $_find_src_files_files; do
# If this is true, the file is part of args, and therefore, unneeded.
if [ "${_find_src_files_args##*$_find_src_files_f}" != "${_find_src_files_args}" ]; then
continue
fi
_find_src_files_result=$(printf '%s\n%s\n' "$_find_src_files_result" "$_find_src_files_f")
done
printf '%s\n' "$_find_src_files_result"
}
# This function generates a list of files to go into the Makefile. It generates
@ -403,10 +435,6 @@ gen_file_list() {
_gen_file_list_contents="$1"
shift
p=$(pwd)
cd "$scriptdir"
if [ "$#" -ge 1 ]; then
_gen_file_list_unneeded="$@"
else
@ -422,7 +450,14 @@ gen_file_list() {
_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
"$_gen_file_list_needle_src" "$_gen_file_list_replacement")
_gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "c" "o")
_gen_file_list_cbases=""
for _gen_file_list_f in $_gen_file_list_replacement; do
_gen_file_list_b=$(basename "$_gen_file_list_f")
_gen_file_list_cbases="$_gen_file_list_cbases src/$_gen_file_list_b"
done
_gen_file_list_replacement=$(replace_exts "$_gen_file_list_cbases" "c" "o")
_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
"$_gen_file_list_needle_obj" "$_gen_file_list_replacement")
@ -434,8 +469,6 @@ gen_file_list() {
_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
"$_gen_file_list_needle_gcno" "$_gen_file_list_replacement")
cd "$p"
printf '%s\n' "$_gen_file_list_contents"
}
@ -466,16 +499,16 @@ gen_std_tests() {
if [ -z "${_gen_std_tests_extra_required##*$_gen_std_tests_t*}" ]; then
printf 'test_%s_%s:\n\t@printf "Skipping %s %s\\n"\n\n' \
"$_gen_std_tests_name" "$_gen_std_tests_t" "$_gen_std_tests_name" \
"$_gen_std_tests_t" >> "$scriptdir/Makefile"
"$_gen_std_tests_t" >> "Makefile"
continue
fi
fi
printf 'test_%s_%s:\n\t@sh tests/test.sh %s %s %s %s %s\n\n' \
"$_gen_std_tests_name" "$_gen_std_tests_t" "$_gen_std_tests_name" \
printf 'test_%s_%s:\n\t@export BC_TEST_OUTPUT_DIR="%s/tests"; sh \$(TESTSDIR)/test.sh %s %s %s %s %s\n\n' \
"$_gen_std_tests_name" "$_gen_std_tests_t" "$builddir" "$_gen_std_tests_name" \
"$_gen_std_tests_t" "$generate_tests" "$time_tests" \
"$*" >> "$scriptdir/Makefile"
"$*" >> "Makefile"
done
}
@ -512,9 +545,9 @@ gen_err_tests() {
for _gen_err_tests_t in $_gen_err_tests_fs; do
printf 'test_%s_error_%s:\n\t@sh tests/error.sh %s %s %s\n\n' \
"$_gen_err_tests_name" "$_gen_err_tests_t" "$_gen_err_tests_name" \
"$_gen_err_tests_t" "$*" >> "$scriptdir/Makefile"
printf 'test_%s_error_%s:\n\t@export BC_TEST_OUTPUT_DIR="%s/tests"; sh \$(TESTSDIR)/error.sh %s %s %s\n\n' \
"$_gen_err_tests_name" "$_gen_err_tests_t" "$builddir" "$_gen_err_tests_name" \
"$_gen_err_tests_t" "$*" >> "Makefile"
done
@ -566,10 +599,10 @@ gen_script_tests() {
_gen_script_tests_b=$(basename "$_gen_script_tests_f" ".${_gen_script_tests_name}")
printf 'test_%s_script_%s:\n\t@sh tests/script.sh %s %s %s 1 %s %s %s\n\n' \
"$_gen_script_tests_name" "$_gen_script_tests_b" "$_gen_script_tests_name" \
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' \
"$_gen_script_tests_name" "$_gen_script_tests_b" "$builddir" "$_gen_script_tests_name" \
"$_gen_script_tests_f" "$_gen_script_tests_extra_math" "$_gen_script_tests_generate" \
"$_gen_script_tests_time" "$*" >> "$scriptdir/Makefile"
"$_gen_script_tests_time" "$*" >> "Makefile"
done
}
@ -594,6 +627,8 @@ set_default() {
dc.tty_mode) dc_default_tty_mode="$_set_default_on" ;;
bc.prompt) bc_default_prompt="$_set_default_on" ;;
dc.prompt) dc_default_prompt="$_set_default_on" ;;
bc.expr_exit) bc_default_expr_exit="$_set_default_on";;
dc.expr_exit) dc_default_expr_exit="$_set_default_on";;
?) usage "Invalid setting: $_set_default_name" ;;
esac
@ -656,6 +691,8 @@ bc_default_tty_mode=1
dc_default_tty_mode=0
bc_default_prompt=""
dc_default_prompt=""
bc_default_expr_exit=1
dc_default_expr_exit=1
# getopts is a POSIX utility, but it cannot handle long options. Thus, the
# handling of long options is done by hand, and that's the reason that short and
@ -946,12 +983,12 @@ executable="BC_EXEC"
tests="test_bc timeconst test_dc"
bc_test="@tests/all.sh bc $extra_math 1 $generate_tests $time_tests \$(BC_EXEC)"
bc_test_np="@tests/all.sh -n bc $extra_math 1 $generate_tests $time_tests \$(BC_EXEC)"
dc_test="@tests/all.sh dc $extra_math 1 $generate_tests $time_tests \$(DC_EXEC)"
dc_test_np="@tests/all.sh -n dc $extra_math 1 $generate_tests $time_tests \$(DC_EXEC)"
bc_test="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/all.sh bc $extra_math 1 $generate_tests $time_tests \$(BC_EXEC)"
bc_test_np="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/all.sh -n bc $extra_math 1 $generate_tests $time_tests \$(BC_EXEC)"
dc_test="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/all.sh dc $extra_math 1 $generate_tests $time_tests \$(DC_EXEC)"
dc_test_np="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/all.sh -n dc $extra_math 1 $generate_tests $time_tests \$(DC_EXEC)"
timeconst="@tests/bc/timeconst.sh tests/bc/scripts/timeconst.bc \$(BC_EXEC)"
timeconst="@export BC_TEST_OUTPUT_DIR=\"$builddir/tests\"; \$(TESTSDIR)/bc/timeconst.sh \$(TESTSDIR)/bc/scripts/timeconst.bc \$(BC_EXEC)"
# In order to have cleanup at exit, we need to be in
# debug mode, so don't run valgrind without that.
@ -999,6 +1036,11 @@ if [ "$library" -ne 0 ]; then
test_bc_history_prereqs=" test_bc_history_skip"
test_dc_history_prereqs=" test_dc_history_skip"
install_prereqs=" install_library"
uninstall_prereqs=" uninstall_library"
install_man_prereqs=" install_bcl_manpage"
uninstall_man_prereqs=" uninstall_bcl_manpage"
elif [ "$bc_only" -eq 1 ]; then
bc=1
@ -1151,6 +1193,24 @@ if [ -z "${LIBDIR+set}" ]; then
LIBDIR="$PREFIX/lib"
fi
if [ -z "${PC_PATH+set}" ]; then
set +e
command -v pkg-config > /dev/null
err=$?
set -e
if [ "$err" -eq 0 ]; then
PC_PATH=$(pkg-config --variable=pc_path pkg-config)
PC_PATH="${PC_PATH%%:*}"
else
PC_PATH=""
fi
fi
# Set a default for the DATAROOTDIR. This is done if either manpages will be
# installed, or locales are enabled because that's probably where NLS_PATH
# points.
@ -1195,14 +1255,14 @@ if [ "$nls" -ne 0 ]; then
flags="-DBC_ENABLE_NLS=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
flags="$flags -DBC_ENABLE_HISTORY=$hist -DBC_ENABLE_LIBRARY=0 -DBC_ENABLE_AFL=0"
flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/"
flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I$scriptdir/include/"
flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
"$CC" $CPPFLAGS $CFLAGS $flags -c "src/vm.c" -o "$scriptdir/vm.o" > /dev/null 2>&1
"$CC" $CPPFLAGS $CFLAGS $flags -c "$scriptdir/src/vm.c" -o "./vm.o" > /dev/null 2>&1
err="$?"
rm -rf "$scriptdir/vm.o"
rm -rf "./vm.o"
# If this errors, it is probably because of building on Windows,
# and NLS is not supported on Windows, so disable it.
@ -1218,11 +1278,11 @@ if [ "$nls" -ne 0 ]; then
printf 'NLS works.\n\n'
printf 'Testing gencat...\n'
gencat "$scriptdir/en_US.cat" "$scriptdir/locales/en_US.msg" > /dev/null 2>&1
gencat "./en_US.cat" "$scriptdir/locales/en_US.msg" > /dev/null 2>&1
err="$?"
rm -rf "$scriptdir/en_US.cat"
rm -rf "./en_US.cat"
if [ "$err" -ne 0 ]; then
printf 'gencat does not work.\n'
@ -1279,14 +1339,14 @@ if [ "$hist" -eq 1 ]; then
flags="-DBC_ENABLE_HISTORY=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
flags="$flags -DBC_ENABLE_NLS=$nls -DBC_ENABLE_LIBRARY=0 -DBC_ENABLE_AFL=0"
flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/"
flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I$scriptdir/include/"
flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
"$CC" $CPPFLAGS $CFLAGS $flags -c "src/history.c" -o "$scriptdir/history.o" > /dev/null 2>&1
"$CC" $CPPFLAGS $CFLAGS $flags -c "$scriptdir/src/history.c" -o "./history.o" > /dev/null 2>&1
err="$?"
rm -rf "$scriptdir/history.o"
rm -rf "./history.o"
# If this errors, it is probably because of building on Windows,
# and history is not supported on Windows, so disable it.
@ -1312,7 +1372,7 @@ if [ "$hist" -eq 0 ] || [ "$vg" -ne 0 ]; then
test_dc_history_prereqs=" test_dc_history_skip"
history_tests="@printf 'Skipping history tests...\\\\n'"
else
history_tests="@printf '\$(TEST_STARS)\\\\n\\\\nRunning history tests...\\\\n\\\\n' \&\& tests/history.sh bc -a \&\& tests/history.sh dc -a \&\& printf '\\\\nAll history tests passed.\\\\n\\\\n\$(TEST_STARS)\\\\n'"
history_tests="@printf '\$(TEST_STARS)\\\\n\\\\nRunning history tests...\\\\n\\\\n' \&\& \$(TESTSDIR)/history.sh bc -a \&\& \$(TESTSDIR)/history.sh dc -a \&\& printf '\\\\nAll history tests passed.\\\\n\\\\n\$(TEST_STARS)\\\\n'"
fi
# Test OpenBSD. This is not in an if statement because regardless of whatever
@ -1327,7 +1387,7 @@ set +e
printf 'Testing for OpenBSD...\n'
flags="-DBC_TEST_OPENBSD -DBC_ENABLE_AFL=0"
"$CC" $CPPFLAGS $CFLAGS $flags -I./include -E "include/status.h" > /dev/null 2>&1
"$CC" $CPPFLAGS $CFLAGS $flags "-I$scriptdir/include" -E "$scriptdir/include/status.h" > /dev/null 2>&1
err="$?"
@ -1403,14 +1463,46 @@ else
headers="$headers \$(DC_HEADERS)"
fi
# This convoluted mess does pull the version out. If you change the format of
# include/version.h, you may have to change this line.
version=$(cat "$scriptdir/include/version.h" | grep "VERSION " - | awk '{ print $3 }' -)
if [ "$library" -ne 0 ]; then
unneeded="$unneeded args.c opt.c read.c file.c main.c"
unneeded="$unneeded lang.c lex.c parse.c program.c"
unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
headers="$headers \$(LIBRARY_HEADERS)"
if [ "$PC_PATH" != "" ]; then
contents=$(cat "$scriptdir/bcl.pc.in")
contents=$(replace "$contents" "INCLUDEDIR" "$INCLUDEDIR")
contents=$(replace "$contents" "LIBDIR" "$LIBDIR")
contents=$(replace "$contents" "VERSION" "$version")
printf '%s\n' "$contents" > "./bcl.pc"
pkg_config_install="\$(SAFE_INSTALL) \$(PC_INSTALL_ARGS) \"\$(BCL_PC)\" \"\$(DESTDIR)\$(PC_PATH)/\$(BCL_PC)\""
pkg_config_uninstall="\$(RM) -f \"\$(DESTDIR)\$(PC_PATH)/\$(BCL_PC)\""
else
pkg_config_install=""
pkg_config_uninstall=""
fi
else
unneeded="$unneeded library.c"
PC_PATH=""
pkg_config_install=""
pkg_config_uninstall=""
fi
# library.c is not needed under normal circumstances.
@ -1444,6 +1536,8 @@ dc_script_tests=$(gen_script_test_targets dc)
dc_err_tests=$(gen_err_test_targets dc)
# Print out the values; this is for debugging.
printf 'Version: %s\n' "$version"
if [ "$bc" -ne 0 ]; then
printf 'Building bc\n'
else
@ -1479,6 +1573,7 @@ printf 'MANDIR=%s\n' "$MANDIR"
printf 'MAN1DIR=%s\n' "$MAN1DIR"
printf 'MAN3DIR=%s\n' "$MAN3DIR"
printf 'NLSPATH=%s\n' "$NLSPATH"
printf 'PC_PATH=%s\n' "$PC_PATH"
printf 'EXECSUFFIX=%s\n' "$EXECSUFFIX"
printf 'EXECPREFIX=%s\n' "$EXECPREFIX"
printf 'DESTDIR=%s\n' "$DESTDIR"
@ -1495,6 +1590,8 @@ printf 'bc.tty_mode=%s\n' "$bc_default_tty_mode"
printf 'dc.tty_mode=%s\n' "$dc_default_tty_mode"
printf 'bc.prompt=%s\n' "$bc_default_prompt"
printf 'dc.prompt=%s\n' "$dc_default_prompt"
printf 'bc.expr_exit=%s\n' "$bc_default_expr_exit"
printf 'dc.expr_exit=%s\n' "$dc_default_expr_exit"
# This is where the real work begins. This is the point at which the Makefile.in
# template is edited and output to the Makefile.
@ -1518,11 +1615,15 @@ src_files=$(find_src_files $unneeded)
for f in $src_files; do
o=$(replace_ext "$f" "c" "o")
SRC_TARGETS=$(printf '%s\n\n%s: %s %s\n\t$(CC) $(CFLAGS) -o %s -c %s\n' \
o=$(basename "$o")
SRC_TARGETS=$(printf '%s\n\nsrc/%s: src %s %s\n\t$(CC) $(CFLAGS) -o src/%s -c %s\n' \
"$SRC_TARGETS" "$o" "$headers" "$f" "$o" "$f")
done
# Replace all the placeholders.
contents=$(replace "$contents" "ROOTDIR" "$scriptdir")
contents=$(replace "$contents" "BUILDDIR" "$builddir")
contents=$(replace "$contents" "HEADERS" "$headers")
contents=$(replace "$contents" "BC_ENABLED" "$bc")
@ -1583,6 +1684,10 @@ contents=$(replace "$contents" "UNINSTALL_MAN_PREREQS" "$uninstall_man_prereqs")
contents=$(replace "$contents" "UNINSTALL_PREREQS" "$uninstall_prereqs")
contents=$(replace "$contents" "UNINSTALL_LOCALES_PREREQS" "$uninstall_locales_prereqs")
contents=$(replace "$contents" "PC_PATH" "$PC_PATH")
contents=$(replace "$contents" "PKG_CONFIG_INSTALL" "$pkg_config_install")
contents=$(replace "$contents" "PKG_CONFIG_UNINSTALL" "$pkg_config_uninstall")
contents=$(replace "$contents" "DEFAULT_TARGET" "$default_target")
contents=$(replace "$contents" "DEFAULT_TARGET_PREREQS" "$default_target_prereqs")
contents=$(replace "$contents" "DEFAULT_TARGET_CMD" "$default_target_cmd")
@ -1630,9 +1735,11 @@ contents=$(replace "$contents" "BC_DEFAULT_TTY_MODE" "$bc_default_tty_mode")
contents=$(replace "$contents" "DC_DEFAULT_TTY_MODE" "$dc_default_tty_mode")
contents=$(replace "$contents" "BC_DEFAULT_PROMPT" "$bc_default_prompt")
contents=$(replace "$contents" "DC_DEFAULT_PROMPT" "$dc_default_prompt")
contents=$(replace "$contents" "BC_DEFAULT_EXPR_EXIT" "$bc_default_expr_exit")
contents=$(replace "$contents" "DC_DEFAULT_EXPR_EXIT" "$dc_default_expr_exit")
# Do the first print to the Makefile.
printf '%s\n%s\n\n' "$contents" "$SRC_TARGETS" > "$scriptdir/Makefile"
printf '%s\n%s\n\n' "$contents" "$SRC_TARGETS" > "Makefile"
# Generate the individual test targets.
if [ "$bc" -ne 0 ]; then
@ -1647,12 +1754,11 @@ if [ "$dc" -ne 0 ]; then
gen_err_tests dc $dc_test_exec
fi
cd "$scriptdir"
# Copy the correct manuals to the expected places.
cp -f manuals/bc/$manpage_args.1.md manuals/bc.1.md
cp -f manuals/bc/$manpage_args.1 manuals/bc.1
cp -f manuals/dc/$manpage_args.1.md manuals/dc.1.md
cp -f manuals/dc/$manpage_args.1 manuals/dc.1
mkdir -p manuals
cp -f "$scriptdir/manuals/bc/$manpage_args.1.md" manuals/bc.1.md
cp -f "$scriptdir/manuals/bc/$manpage_args.1" manuals/bc.1
cp -f "$scriptdir/manuals/dc/$manpage_args.1.md" manuals/dc.1.md
cp -f "$scriptdir/manuals/dc/$manpage_args.1" manuals/dc.1
make clean > /dev/null

View File

@ -183,3 +183,10 @@ Environment variables:
If an integer and non-zero, enable prompt when TTY mode is possible.
Overrides the default, which is prompt %s.
BC_EXPR_EXIT
If an integer and non-zero, exit when expressions or expression files are
given on the command-line, and does not exit when an integer and zero.
Overrides the default, which is %s.

View File

@ -142,3 +142,10 @@ Environment variables:
If an integer and non-zero, enable prompt when TTY mode is possible.
Overrides the default, which is prompt %s.
DC_EXPR_EXIT
If an integer and non-zero, exit when expressions or expression files are
given on the command-line, and does not exit when an integer and zero.
Overrides the default, which is %s.

View File

@ -268,6 +268,10 @@
#define BC_DEFAULT_PROMPT BC_DEFAULT_TTY_MODE
#endif // BC_DEFAULT_PROMPT
#ifndef BC_DEFAULT_EXPR_EXIT
#define BC_DEFAULT_EXPR_EXIT (1)
#endif // BC_DEFAULT_EXPR_EXIT
// All of these set defaults for settings.
#ifndef DC_DEFAULT_SIGINT_RESET
#define DC_DEFAULT_SIGINT_RESET (1)
@ -285,6 +289,10 @@
#define DC_DEFAULT_PROMPT DC_DEFAULT_TTY_MODE
#endif // DC_DEFAULT_PROMPT
#ifndef DC_DEFAULT_EXPR_EXIT
#define DC_DEFAULT_EXPR_EXIT (1)
#endif // DC_DEFAULT_EXPR_EXIT
/// Statuses, which mark either which category of error happened, or some other
/// status that matters.
typedef enum BcStatus {
@ -472,6 +480,10 @@ typedef enum BcErr {
/// Empty statements in POSIX for loop error.
BC_ERR_POSIX_FOR,
/// POSIX's grammar does not allow a function definition right after a
/// semicolon.
BC_ERR_POSIX_FUNC_AFTER_SEMICOLON,
/// Non-POSIX exponential (scientific or engineering) number used error.
BC_ERR_POSIX_EXP_NUM,

View File

@ -37,6 +37,6 @@
#define BC_VERSION_H
/// The current version.
#define VERSION 5.1.1
#define VERSION 5.2.1
#endif // BC_VERSION_H

View File

@ -176,6 +176,9 @@
/// The flag for reset on SIGINT.
#define BC_FLAG_SIGINT (UINTMAX_C(1)<<12)
/// The flag for exiting with expressions.
#define BC_FLAG_EXPR_EXIT (UINTMAX_C(1)<<13)
/// A convenience macro for getting the TTYIN flag.
#define BC_TTYIN (vm.flags & BC_FLAG_TTYIN)
@ -220,6 +223,9 @@
/// A convenience macro for getting the leading zero flag.
#define BC_Z (vm.flags & BC_FLAG_Z)
/// A convenience macro for getting the expression exit flag.
#define BC_EXPR_EXIT (vm.flags & BC_FLAG_EXPR_EXIT)
#if BC_ENABLED
/// A convenience macro for checking if bc is in POSIX mode.

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX erlaubt keine Vergleichsoperatoren außerhalb von if-Anweisungen oder Schleifen"
23 "POSIX benötigt 0 oder 1 Vergleichsoperatoren pro Bedingung"
24 "POSIX erlaubt keinen leeren Ausdruck in einer for-Schleife"
25 "POSIX erlaubt keine exponentielle Notation"
26 "POSIX erlaubt keine Feld-Referenzen als Funktionsparameter"
27 "POSIX erfordert, dass die linke Klammer auf der gleichen Linie wie der Funktionskopf steht"
28 "POSIX erlaubt keine Zuweisung von Strings an Variablen oder Arrays"
25 "POSIX verlangt einen Zeilenumbruch zwischen einem Semikolon und einer Funktionsdefinition"
26 "POSIX erlaubt keine exponentielle Notation"
27 "POSIX erlaubt keine Feld-Referenzen als Funktionsparameter"
28 "POSIX erlaubt keine ungültigen Funktionen"
29 "POSIX erfordert, dass die linke Klammer auf der gleichen Linie wie der Funktionskopf steht"
30 "POSIX erlaubt keine Zuweisung von Strings an Variablen oder Arrays"
$ Runtime errors.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX erlaubt keine Vergleichsoperatoren außerhalb von if-Anweisungen oder Schleifen"
23 "POSIX benötigt 0 oder 1 Vergleichsoperatoren pro Bedingung"
24 "POSIX erlaubt keinen leeren Ausdruck in einer for-Schleife"
25 "POSIX erlaubt keine exponentielle Notation"
26 "POSIX erlaubt keine Feld-Referenzen als Funktionsparameter"
27 "POSIX erfordert, dass die linke Klammer auf der gleichen Linie wie der Funktionskopf steht"
28 "POSIX erlaubt keine Zuweisung von Strings an Variablen oder Arrays"
25 "POSIX verlangt einen Zeilenumbruch zwischen einem Semikolon und einer Funktionsdefinition"
26 "POSIX erlaubt keine exponentielle Notation"
27 "POSIX erlaubt keine Feld-Referenzen als Funktionsparameter"
28 "POSIX erlaubt keine ungültigen Funktionen"
29 "POSIX erfordert, dass die linke Klammer auf der gleichen Linie wie der Funktionskopf steht"
30 "POSIX erlaubt keine Zuweisung von Strings an Variablen oder Arrays"
$ Runtime errors.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX does not allow comparison operators outside if statements or loops"
23 "POSIX requires 0 or 1 comparison operators per condition"
24 "POSIX requires all 3 parts of a for loop to be non-empty"
25 "POSIX does not allow exponential notation"
26 "POSIX does not allow array references as function parameters"
27 "POSIX requires the left brace be on the same line as the function header"
28 "POSIX does not allow strings to be assigned to variables or arrays"
25 "POSIX requires a newline between a semicolon and a function definition",
26 "POSIX does not allow exponential notation"
27 "POSIX does not allow array references as function parameters"
28 "POSIX does not allow void functions",
29 "POSIX requires the left brace be on the same line as the function header"
30 "POSIX does not allow strings to be assigned to variables or arrays"
$ Runtime errors.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX no permite operadores de comparación aparte de \"if\" expresión o bucles"
23 "POSIX requiere 0 o 1 operadores de comparisón para cada condición"
24 "POSIX requiere todos 3 partes de una bucla que no esta vacío"
25 "POSIX no permite una notación exponencial"
26 "POSIX no permite una referencia a una matriz como un parámetro de función"
27 "POSIX requiere el llave de la izquierda que sea en la misma línea que los parámetros de la función"
28 "POSIX no permite asignar cadenas a variables o matrices"
25 "POSIX requiere una nueva línea entre un punto y coma y una definición de función"
26 "POSIX no permite una notación exponencial"
27 "POSIX no permite una referencia a una matriz como un parámetro de función"
28 "POSIX no permite funciones void"
29 "POSIX requiere el llave de la izquierda que sea en la misma línea que los parámetros de la función"
30 "POSIX no permite asignar cadenas a variables o matrices"
$ Runtime errors.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX no permite operadores de comparación aparte de \"if\" expresión o bucles"
23 "POSIX requiere 0 o 1 operadores de comparisón para cada condición"
24 "POSIX requiere todos 3 partes de una bucla que no esta vacío"
25 "POSIX no permite una notación exponencial"
26 "POSIX no permite una referencia a una matriz como un parámetro de función"
27 "POSIX requiere el llave de la izquierda que sea en la misma línea que los parámetros de la función"
28 "POSIX no permite asignar cadenas a variables o matrices"
25 "POSIX requiere una nueva línea entre un punto y coma y una definición de función"
26 "POSIX no permite una notación exponencial"
27 "POSIX no permite una referencia a una matriz como un parámetro de función"
28 "POSIX no permite funciones void"
29 "POSIX requiere el llave de la izquierda que sea en la misma línea que los parámetros de la función"
30 "POSIX no permite asignar cadenas a variables o matrices"
$ Runtime errors.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX interdit les opérateurs de comparaison en dehors des expressions 'if' ou des boucles"
23 "POSIX impose 0 ou 1 opérateur de comparaison par condition"
24 "POSIX interdit une expression vide dans une boucle 'for'"
25 "POSIX interdit la notation exponentielle"
26 "POSIX interdit les références à un tableau dans les paramètres d'une fonction"
27 "POSIX impose que l'en-tête de la fonction et le '{' soient sur la même ligne"
28 "POSIX interdit pas d'assigner des chaînes de caractères à des variables ou à des tableaux"
25 "POSIX exige une nouvelle ligne entre un point-virgule et une définition de fonction"
26 "POSIX interdit la notation exponentielle"
27 "POSIX interdit les références à un tableau dans les paramètres d'une fonction"
28 "POSIX n'autorise pas les fonctions void"
29 "POSIX impose que l'en-tête de la fonction et le '{' soient sur la même ligne"
30 "POSIX interdit pas d'assigner des chaînes de caractères à des variables ou à des tableaux"
$ Runtime errors.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX interdit les opérateurs de comparaison en dehors des expressions 'if' ou des boucles"
23 "POSIX impose 0 ou 1 opérateur de comparaison par condition"
24 "POSIX interdit une expression vide dans une boucle 'for'"
25 "POSIX interdit la notation exponentielle"
26 "POSIX interdit les références à un tableau dans les paramètres d'une fonction"
27 "POSIX impose que l'en-tête de la fonction et le '{' soient sur la même ligne"
28 "POSIX interdit pas d'assigner des chaînes de caractères à des variables ou à des tableaux"
25 "POSIX exige une nouvelle ligne entre un point-virgule et une définition de fonction."
26 "POSIX interdit la notation exponentielle"
27 "POSIX interdit les références à un tableau dans les paramètres d'une fonction"
28 "POSIX n'autorise pas les fonctions void"
29 "POSIX impose que l'en-tête de la fonction et le '{' soient sur la même ligne"
30 "POSIX interdit pas d'assigner des chaînes de caractères à des variables ou à des tableaux"
$ Runtime errors.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX は if 文やループの外の比較演算子を許可しません。"
23 "POSIXは条件ごとに0または1の比較演算子を必要とします。"
24 "POSIXはforループの3つの部分がすべて空でないことを要求します。"
25 "POSIXは指数表記を許可しません。"
26 "POSIX は関数パラメータとして配列参照を許可しません。"
27 "POSIXでは、関数ヘッダと同じ行に左中括弧があることが必要です。"
28 "POSIXでは、変数や配列に文字列を割り当てることはできません。"
25 "POSIXでは、セミコロンと関数定義の間に改行を入れる必要があります。"
26 "POSIXは指数表記を許可しません。"
27 "POSIX は関数パラメータとして配列参照を許可しません。"
28 "POSIXではvoid関数を認めていません。"
29 "POSIXでは、関数ヘッダと同じ行に左中括弧があることが必要です。"
30 "POSIXでは、変数や配列に文字列を割り当てることはできません。"
$ ランタイムエラー。
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX は if 文やループの外の比較演算子を許可しません。"
23 "POSIXは条件ごとに0または1の比較演算子を必要とします。"
24 "POSIXはforループの3つの部分がすべて空でないことを要求します。"
25 "POSIXは指数表記を許可しません。"
26 "POSIX は関数パラメータとして配列参照を許可しません。"
27 "POSIXでは、関数ヘッダと同じ行に左中括弧があることが必要です。"
28 "POSIXでは、変数や配列に文字列を割り当てることはできません。"
25 "POSIXでは、セミコロンと関数定義の間に改行を入れる必要があります。"
26 "POSIXは指数表記を許可しません。"
27 "POSIX は関数パラメータとして配列参照を許可しません。"
28 "POSIXではvoid関数を認めていません。"
29 "POSIXでは、関数ヘッダと同じ行に左中括弧があることが必要です。"
30 "POSIXでは、変数や配列に文字列を割り当てることはできません。"
$ ランタイムエラー。
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX laat geen vergelijking toe tussen operatoren buiten als verklaringen of lussen"
23 "POSIX vereist 0 of 1 vergelijkingsoperator per conditie"
24 "POSIX vereist dat alle 3 de delen van een lus niet leeg zijn"
25 "POSIX laat geen exponentiële notatie toe"
26 "POSIX staat geen arrayreferenties toe als functieparameters"
27 "POSIX vereist dat de linkse beugel op dezelfde regel staat als de functiehoofding"
28 "POSIX staat niet toe dat strings worden toegewezen aan variabelen of arrays"
25 "POSIX vereist een nieuwe regel tussen een puntkomma en een functiedefinitie"
26 "POSIX laat geen exponentiële notatie toe"
27 "POSIX staat geen arrayreferenties toe als functieparameters"
28 "POSIX staat geen lege functies toe"
29 "POSIX vereist dat de linkse beugel op dezelfde regel staat als de functiehoofding"
30 "POSIX staat niet toe dat strings worden toegewezen aan variabelen of arrays"
$ Runtime fouten.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX laat geen vergelijking toe tussen operatoren buiten als verklaringen of lussen"
23 "POSIX vereist 0 of 1 vergelijkingsoperator per conditie"
24 "POSIX vereist dat alle 3 de delen van een lus niet leeg zijn"
25 "POSIX laat geen exponentiële notatie toe"
26 "POSIX staat geen arrayreferenties toe als functieparameters"
27 "POSIX vereist dat de linkse beugel op dezelfde regel staat als de functiehoofding"
28 "POSIX staat niet toe dat strings worden toegewezen aan variabelen of arrays"
25 "POSIX vereist een nieuwe regel tussen een puntkomma en een functiedefinitie"
26 "POSIX laat geen exponentiële notatie toe"
27 "POSIX staat geen arrayreferenties toe als functieparameters"
28 "POSIX staat geen lege functies toe"
29 "POSIX vereist dat de linkse beugel op dezelfde regel staat als de functiehoofding"
30 "POSIX staat niet toe dat strings worden toegewezen aan variabelen of arrays"
$ Runtime fouten.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX nie pozwala na porównywanie operatorów na zewnątrz, jeśli deklaracje lub pętle"
23 "POSIX wymaga 0 lub 1 operatora porównawczego na jeden warunek"
24 "POSIX wymaga, aby wszystkie 3 części pętli nie były puste"
25 "POSIX nie pozwala na notację wykładniczą"
26 "POSIX nie zezwala na odniesienia do tablicy jako parametrów funkcji"
27 "POSIX wymaga, aby lewe usztywnienie znajdowało się na tej samej linii co nagłówek funkcji"
28 "POSIX nie pozwala na przypisywanie ciągów znaków do zmiennych lub tablic"
25 "POSIX wymaga nowej linii pomiędzy średnikiem a definicją funkcji"
26 "POSIX nie pozwala na notację wykładniczą"
27 "POSIX nie zezwala na odniesienia do tablicy jako parametrów funkcji"
28 "POSIX nie dopuszcza funkcji void"
29 "POSIX wymaga, aby lewe usztywnienie znajdowało się na tej samej linii co nagłówek funkcji"
30 "POSIX nie pozwala na przypisywanie ciągów znaków do zmiennych lub tablic"
$ Błędy Runtime'u.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX nie pozwala na porównywanie operatorów na zewnątrz, jeśli deklaracje lub pętle"
23 "POSIX wymaga 0 lub 1 operatora porównawczego na jeden warunek"
24 "POSIX wymaga, aby wszystkie 3 części pętli nie były puste"
25 "POSIX nie pozwala na notację wykładniczą"
26 "POSIX nie zezwala na odniesienia do tablicy jako parametrów funkcji"
27 "POSIX wymaga, aby lewe usztywnienie znajdowało się na tej samej linii co nagłówek funkcji"
28 "POSIX nie pozwala na przypisywanie ciągów znaków do zmiennych lub tablic"
25 "POSIX wymaga nowej linii pomiędzy średnikiem a definicją funkcji"
26 "POSIX nie pozwala na notację wykładniczą"
27 "POSIX nie zezwala na odniesienia do tablicy jako parametrów funkcji"
28 "POSIX nie dopuszcza funkcji void"
29 "POSIX wymaga, aby lewe usztywnienie znajdowało się na tej samej linii co nagłówek funkcji"
30 "POSIX nie pozwala na przypisywanie ciągów znaków do zmiennych lub tablic"
$ Błędy Runtime'u.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX não permite operadores de comparação fora das expressões 'if' ou loops"
23 "POSIX requer operadores 0 ou 1 de comparação por condição"
24 "POSIX não permite uma expressão vazia em um loop 'for'"
25 "POSIX não permite notação exponencial"
26 "POSIX não permite referências de matriz como parâmetros de função"
27 "POSIX requer que o cabeçalho da função '{' estejam na mesma linha"
28 "POSIX não permite a atribuição de cadeias de caracteres a variáveis ou matrizes"
25 "POSIX requer uma nova linha entre um ponto-e-vírgula e uma definição de função"
26 "POSIX não permite notação exponencial"
27 "POSIX não permite referências de matriz como parâmetros de função"
28 "POSIX não permite funções nulas"
29 "POSIX requer que o cabeçalho da função '{' estejam na mesma linha"
30 "POSIX não permite a atribuição de cadeias de caracteres a variáveis ou matrizes"
$ Runtime errors.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX não permite operadores de comparação fora das expressões 'if' ou loops"
23 "POSIX requer operadores 0 ou 1 de comparação por condição"
24 "POSIX não permite uma expressão vazia em um loop 'for'"
25 "POSIX não permite notação exponencial"
26 "POSIX não permite referências de matriz como parâmetros de função"
27 "POSIX requer que o cabeçalho da função '{' estejam na mesma linha"
28 "POSIX não permite a atribuição de cadeias de caracteres a variáveis ou matrizes"
25 "POSIX requer uma nova linha entre um ponto-e-vírgula e uma definição de função"
26 "POSIX não permite notação exponencial"
27 "POSIX não permite referências de matriz como parâmetros de função"
28 "POSIX não permite funções nulas"
29 "POSIX requer que o cabeçalho da função '{' estejam na mesma linha"
30 "POSIX não permite a atribuição de cadeias de caracteres a variáveis ou matrizes"
$ Runtime errors.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX не разрешает операторам сравнения выходить за пределы, если утверждения или циклы"
23 "POSIX требует 0 или 1 оператора сравнения на условие"
24 "POSIX требует, чтобы все 3 части петли были непустыми"
25 "POSIX не допускает экспоненциальной нотации"
26 "POSIX не допускает ссылки на массив в качестве параметров функции"
27 "POSIX требует, чтобы левая скобка была на той же линии, что и заголовок функции"
28 "POSIX не позволяет присваивать строки переменным или массивам"
25 "POSIX требует наличия новой строки между точкой с запятой и определением функции"
26 "POSIX не допускает экспоненциальной нотации"
27 "POSIX не допускает ссылки на массив в качестве параметров функции"
28 "POSIX не разрешает функции пустоты"
29 "POSIX требует, чтобы левая скобка была на той же линии, что и заголовок функции"
30 "POSIX не позволяет присваивать строки переменным или массивам"
$ Ошибки выполнения.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX ­¥ à §à¥è ¥â ®¯¥à â®à ¬ áà ¢­¥­¨ï ¢ë室¨âì §  ¯à¥¤¥«ë, ¥á«¨ ã⢥ত¥­¨ï ¨«¨ 横«ë"
23 "POSIX âॡã¥â 0 ¨«¨ 1 ®¯¥à â®à  áà ¢­¥­¨ï ­  ãá«®¢¨¥"
24 "POSIX âॡã¥â, çâ®¡ë ¢á¥ 3 ç á⨠¯¥â«¨ ¡ë«¨ ­¥¯ãáâ묨"
25 "POSIX ­¥ ¤®¯ã᪠¥â íªá¯®­¥­æ¨ «ì­®© ­®â æ¨¨"
26 "POSIX ­¥ ¤®¯ã᪠¥â áá뫪¨ ­  ¬ áᨢ ¢ ª ç¥á⢥ ¯ à ¬¥â஢ ä㭪樨"
27 "POSIX âॡã¥â, çâ®¡ë «¥¢ ï ᪮¡ª  ¡ë«  ­  ⮩ ¦¥ «¨­¨¨, çâ® ¨ § £®«®¢®ª ä㭪樨"
28 "POSIX ­¥ ¯®§¢®«ï¥â ¯à¨á¢ ¨¢ âì áâப¨ ¯¥à¥¬¥­­ë¬ ¨«¨ ¬ áᨢ ¬"
25 "POSIX âॡã¥â ­ «¨ç¨ï ­®¢®© áâப¨ ¬¥¦¤ã â®çª®© á § ¯ï⮩ ¨ ®¯à¥¤¥«¥­¨¥¬ ä㭪樨"
26 "POSIX ­¥ ¤®¯ã᪠¥â íªá¯®­¥­æ¨ «ì­®© ­®â æ¨¨"
27 "POSIX ­¥ ¤®¯ã᪠¥â áá뫪¨ ­  ¬ áᨢ ¢ ª ç¥á⢥ ¯ à ¬¥â஢ ä㭪樨"
28 "POSIX ­¥ à §à¥è ¥â ä㭪樨 ¯ãáâ®âë"
29 "POSIX âॡã¥â, çâ®¡ë «¥¢ ï ᪮¡ª  ¡ë«  ­  ⮩ ¦¥ «¨­¨¨, çâ® ¨ § £®«®¢®ª ä㭪樨"
30 "POSIX ­¥ ¯®§¢®«ï¥â ¯à¨á¢ ¨¢ âì áâப¨ ¯¥à¥¬¥­­ë¬ ¨«¨ ¬ áᨢ ¬"
$ Žè¨¡ª¨ ¢ë¯®«­¥­¨ï.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX не разрешает операторам сравнения выходить за пределы, если утверждения или циклы"
23 "POSIX требует 0 или 1 оператора сравнения на условие"
24 "POSIX требует, чтобы все 3 части петли были непустыми"
25 "POSIX не допускает экспоненциальной нотации"
26 "POSIX не допускает ссылки на массив в качестве параметров функции"
27 "POSIX требует, чтобы левая скобка была на той же линии, что и заголовок функции"
28 "POSIX не позволяет присваивать строки переменным или массивам"
25 "POSIX требует наличия новой строки между точкой с запятой и определением функции"
26 "POSIX не допускает экспоненциальной нотации"
27 "POSIX не допускает ссылки на массив в качестве параметров функции"
28 "POSIX не разрешает функции пустоты"
29 "POSIX требует, чтобы левая скобка была на той же линии, что и заголовок функции"
30 "POSIX не позволяет присваивать строки переменным или массивам"
$ Ошибки выполнения.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX не разрешает операторам сравнения выходить за пределы, если утверждения или циклы"
23 "POSIX требует 0 или 1 оператора сравнения на условие"
24 "POSIX требует, чтобы все 3 части петли были непустыми"
25 "POSIX не допускает экспоненциальной нотации"
26 "POSIX не допускает ссылки на массив в качестве параметров функции"
27 "POSIX требует, чтобы левая скобка была на той же линии, что и заголовок функции"
28 "POSIX не позволяет присваивать строки переменным или массивам"
25 "POSIX требует наличия новой строки между точкой с запятой и определением функции"
26 "POSIX не допускает экспоненциальной нотации"
27 "POSIX не допускает ссылки на массив в качестве параметров функции"
28 "POSIX не разрешает функции пустоты"
29 "POSIX требует, чтобы левая скобка была на той же линии, что и заголовок функции"
30 "POSIX не позволяет присваивать строки переменным или массивам"
$ Ошибки выполнения.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX не разрешает операторам сравнения выходить за пределы, если утверждения или циклы"
23 "POSIX требует 0 или 1 оператора сравнения на условие"
24 "POSIX требует, чтобы все 3 части петли были непустыми"
25 "POSIX не допускает экспоненциальной нотации"
26 "POSIX не допускает ссылки на массив в качестве параметров функции"
27 "POSIX требует, чтобы левая скобка была на той же линии, что и заголовок функции"
28 "POSIX не позволяет присваивать строки переменным или массивам"
25 "POSIX требует наличия новой строки между точкой с запятой и определением функции"
26 "POSIX не допускает экспоненциальной нотации"
27 "POSIX не допускает ссылки на массив в качестве параметров функции"
28 "POSIX не разрешает функции пустоты"
29 "POSIX требует, чтобы левая скобка была на той же линии, что и заголовок функции"
30 "POSIX не позволяет присваивать строки переменным или массивам"
$ Ошибки выполнения.
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX不允许在if语句或循环之外的比较运算符"
23 "POSIX要求每个条件的比较运算符为0或1个"
24 "POSIX要求for循环的所有3个部分必须是非空的"
25 "POSIX不允许使用指数符号"
26 "POSIX不允许数组引用作为函数参数"
27 "POSIX要求左边的括号和函数头在同一行上"
28 "POSIX不允许将字符串分配给变量或数组"
25 "POSIX要求在分号和函数定义之间使用换行符"
26 "POSIX不允许使用指数符号"
27 "POSIX不允许数组引用作为函数参数"
28 "POSIX不允许无效函数"
29 "POSIX要求左边的括号和函数头在同一行上"
30 "POSIX不允许将字符串分配给变量或数组"
$ 运行时错误。
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX不允许在if语句或循环之外的比较运算符"
23 "POSIX要求每个条件的比较运算符为0或1个"
24 "POSIX要求for循环的所有3个部分必须是非空的"
25 "POSIX不允许使用指数符号"
26 "POSIX不允许数组引用作为函数参数"
27 "POSIX要求左边的括号和函数头在同一行上"
28 "POSIX不允许将字符串分配给变量或数组"
25 "POSIX要求在分号和函数定义之间使用换行符"
26 "POSIX不允许使用指数符号"
27 "POSIX不允许数组引用作为函数参数"
28 "POSIX不允许无效函数"
29 "POSIX要求左边的括号和函数头在同一行上"
30 "POSIX不允许将字符串分配给变量或数组"
$ 运行时错误。
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX不允许在if语句或循环之外的比较运算符"
23 "POSIX要求每个条件的比较运算符为0或1个"
24 "POSIX要求for循环的所有3个部分必须是非空的"
25 "POSIX不允许使用指数符号"
26 "POSIX不允许数组引用作为函数参数"
27 "POSIX要求左边的括号和函数头在同一行上"
28 "POSIX不允许将字符串分配给变量或数组"
25 "POSIX要求在分号和函数定义之间使用换行符"
26 "POSIX不允许使用指数符号"
27 "POSIX不允许数组引用作为函数参数"
28 "POSIX不允许无效函数"
29 "POSIX要求左边的括号和函数头在同一行上"
30 "POSIX不允许将字符串分配给变量或数组"
$ 运行时错误。
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX不允许在if语句或循环之外的比较运算符"
23 "POSIX要求每个条件的比较运算符为0或1个"
24 "POSIX要求for循环的所有3个部分必须是非空的"
25 "POSIX不允许使用指数符号"
26 "POSIX不允许数组引用作为函数参数"
27 "POSIX要求左边的括号和函数头在同一行上"
28 "POSIX不允许将字符串分配给变量或数组"
25 "POSIX要求在分号和函数定义之间使用换行符"
26 "POSIX不允许使用指数符号"
27 "POSIX不允许数组引用作为函数参数"
28 "POSIX不允许无效函数"
29 "POSIX要求左边的括号和函数头在同一行上"
30 "POSIX不允许将字符串分配给变量或数组"
$ 运行时错误。
$set 5

View File

@ -77,10 +77,12 @@ $set 4
22 "POSIX不允许在if语句或循环之外的比较运算符"
23 "POSIX要求每个条件的比较运算符为0或1个"
24 "POSIX要求for循环的所有3个部分必须是非空的"
25 "POSIX不允许使用指数符号"
26 "POSIX不允许数组引用作为函数参数"
27 "POSIX要求左边的括号和函数头在同一行上"
28 "POSIX不允许将字符串分配给变量或数组"
25 "POSIX要求在分号和函数定义之间使用换行符"
26 "POSIX不允许使用指数符号"
27 "POSIX不允许数组引用作为函数参数"
28 "POSIX不允许无效函数"
29 "POSIX要求左边的括号和函数头在同一行上"
30 "POSIX不允许将字符串分配给变量或数组"
$ 运行时错误。
$set 5

View File

@ -2552,6 +2552,19 @@ This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]BC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes bc(1) exit after executing the
expressions and expression files, and a non-zero value makes bc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
bc(1) returns the following exit statuses:

View File

@ -2129,6 +2129,17 @@ bc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**BC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes bc(1) exit
after executing the expressions and expression files, and a non-zero value
makes bc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
bc(1) returns the following exit statuses:

View File

@ -1400,6 +1400,19 @@ This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]BC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes bc(1) exit after executing the
expressions and expression files, and a non-zero value makes bc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
bc(1) returns the following exit statuses:

View File

@ -1149,6 +1149,17 @@ bc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**BC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes bc(1) exit
after executing the expressions and expression files, and a non-zero value
makes bc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
bc(1) returns the following exit statuses:

View File

@ -1400,6 +1400,19 @@ This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]BC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes bc(1) exit after executing the
expressions and expression files, and a non-zero value makes bc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
bc(1) returns the following exit statuses:

View File

@ -1149,6 +1149,17 @@ bc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**BC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes bc(1) exit
after executing the expressions and expression files, and a non-zero value
makes bc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
bc(1) returns the following exit statuses:

View File

@ -1400,6 +1400,19 @@ This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]BC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes bc(1) exit after executing the
expressions and expression files, and a non-zero value makes bc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
bc(1) returns the following exit statuses:

View File

@ -1149,6 +1149,17 @@ bc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**BC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes bc(1) exit
after executing the expressions and expression files, and a non-zero value
makes bc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
bc(1) returns the following exit statuses:

View File

@ -1400,6 +1400,19 @@ This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]BC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes bc(1) exit after executing the
expressions and expression files, and a non-zero value makes bc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
bc(1) returns the following exit statuses:

View File

@ -1149,6 +1149,17 @@ bc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**BC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes bc(1) exit
after executing the expressions and expression files, and a non-zero value
makes bc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
bc(1) returns the following exit statuses:

View File

@ -2552,6 +2552,19 @@ This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]BC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes bc(1) exit after executing the
expressions and expression files, and a non-zero value makes bc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
bc(1) returns the following exit statuses:

View File

@ -2129,6 +2129,17 @@ bc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**BC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes bc(1) exit
after executing the expressions and expression files, and a non-zero value
makes bc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
bc(1) returns the following exit statuses:

View File

@ -2552,6 +2552,19 @@ This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]BC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes bc(1) exit after executing the
expressions and expression files, and a non-zero value makes bc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
bc(1) returns the following exit statuses:

View File

@ -2129,6 +2129,17 @@ bc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**BC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes bc(1) exit
after executing the expressions and expression files, and a non-zero value
makes bc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
bc(1) returns the following exit statuses:

View File

@ -2552,6 +2552,19 @@ This environment variable and the \f[B]BC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]BC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes bc(1) exit after executing the
expressions and expression files, and a non-zero value makes bc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
bc(1) returns the following exit statuses:

View File

@ -2129,6 +2129,17 @@ bc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**BC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes bc(1) exit
after executing the expressions and expression files, and a non-zero value
makes bc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
bc(1) returns the following exit statuses:

View File

@ -83,6 +83,23 @@ where `<config>` is either one of `Debug`, `ReleaseMD`, or `ReleaseMT`.
Building `bc`, `dc`, and `bcl` (the library) is more complex than on Windows
because many build options are supported.
### Out-of-Source Builds
Out-of-source builds are done by calling `configure.sh` from the directory where
the build will happen. The `Makefile` is generated into that directory, and the
build can happen normally from there.
For example, if the source is in `bc`, the build should happen in `build`, then
call `configure.sh` and `make` like so:
```
../bc/configure.sh
make
```
***WARNING***: The path to `configure.sh` from the build directory must not have
spaces because `make` does not support target names with spaces.
### Cross Compiling
To cross-compile this `bc`, an appropriate compiler must be present and assigned

View File

@ -1340,6 +1340,19 @@ This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]DC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes dc(1) exit after executing the
expressions and expression files, and a non-zero value makes dc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
dc(1) returns the following exit statuses:

View File

@ -1190,6 +1190,17 @@ dc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**DC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes dc(1) exit
after executing the expressions and expression files, and a non-zero value
makes dc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
dc(1) returns the following exit statuses:

View File

@ -1135,6 +1135,19 @@ This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]DC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes dc(1) exit after executing the
expressions and expression files, and a non-zero value makes dc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
dc(1) returns the following exit statuses:

View File

@ -1025,6 +1025,17 @@ dc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**DC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes dc(1) exit
after executing the expressions and expression files, and a non-zero value
makes dc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
dc(1) returns the following exit statuses:

View File

@ -1135,6 +1135,19 @@ This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]DC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes dc(1) exit after executing the
expressions and expression files, and a non-zero value makes dc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
dc(1) returns the following exit statuses:

View File

@ -1025,6 +1025,17 @@ dc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**DC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes dc(1) exit
after executing the expressions and expression files, and a non-zero value
makes dc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
dc(1) returns the following exit statuses:

View File

@ -1135,6 +1135,19 @@ This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]DC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes dc(1) exit after executing the
expressions and expression files, and a non-zero value makes dc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
dc(1) returns the following exit statuses:

View File

@ -1025,6 +1025,17 @@ dc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**DC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes dc(1) exit
after executing the expressions and expression files, and a non-zero value
makes dc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
dc(1) returns the following exit statuses:

View File

@ -1135,6 +1135,19 @@ This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]DC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes dc(1) exit after executing the
expressions and expression files, and a non-zero value makes dc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
dc(1) returns the following exit statuses:

View File

@ -1025,6 +1025,17 @@ dc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**DC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes dc(1) exit
after executing the expressions and expression files, and a non-zero value
makes dc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
dc(1) returns the following exit statuses:

View File

@ -1340,6 +1340,19 @@ This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]DC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes dc(1) exit after executing the
expressions and expression files, and a non-zero value makes dc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
dc(1) returns the following exit statuses:

View File

@ -1190,6 +1190,17 @@ dc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**DC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes dc(1) exit
after executing the expressions and expression files, and a non-zero value
makes dc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
dc(1) returns the following exit statuses:

View File

@ -1340,6 +1340,19 @@ This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]DC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes dc(1) exit after executing the
expressions and expression files, and a non-zero value makes dc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
dc(1) returns the following exit statuses:

View File

@ -1190,6 +1190,17 @@ dc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**DC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes dc(1) exit
after executing the expressions and expression files, and a non-zero value
makes dc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
dc(1) returns the following exit statuses:

View File

@ -1340,6 +1340,19 @@ This environment variable and the \f[B]DC_TTY_MODE\f[R] environment
variable override the default, which can be queried with the
\f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.TP
\f[B]DC_EXPR_EXIT\f[R]
If any expressions or expression files are given on the command-line
with \f[B]-e\f[R], \f[B]--expression\f[R], \f[B]-f\f[R], or
\f[B]--file\f[R], then if this environment variable exists and contains
an integer, a non-zero value makes dc(1) exit after executing the
expressions and expression files, and a non-zero value makes dc(1) not
exit.
.RS
.PP
This environment variable overrides the default, which can be queried
with the \f[B]-h\f[R] or \f[B]--help\f[R] options.
.RE
.SH EXIT STATUS
.PP
dc(1) returns the following exit statuses:

View File

@ -1190,6 +1190,17 @@ dc(1) recognizes the following environment variables:
override the default, which can be queried with the **-h** or **-\-help**
options.
**DC_EXPR_EXIT**
: If any expressions or expression files are given on the command-line with
**-e**, **-\-expression**, **-f**, or **-\-file**, then if this environment
variable exists and contains an integer, a non-zero value makes dc(1) exit
after executing the expressions and expression files, and a non-zero value
makes dc(1) not exit.
This environment variable overrides the default, which can be queried with
the **-h** or **-\-help** options.
# EXIT STATUS
dc(1) returns the following exit statuses:

View File

@ -29,7 +29,7 @@
# Print usage and exit with an error.
usage() {
printf "usage: %s install_dir exec_suffix\n" "$0" 1>&2
printf "usage: %s install_dir exec_suffix [bindir]\n" "$0" 1>&2
exit 1
}
@ -49,7 +49,12 @@ shift
exec_suffix="$1"
shift
bindir="$scriptdir/../bin"
if [ "$#" -gt 0 ]; then
bindir="$1"
shift
else
bindir="$scriptdir/../bin"
fi
# Install or symlink, depending on the type of file. If it's a file, install it.
# If it's a symlink, create an equivalent in the install directory.

View File

@ -49,9 +49,6 @@ def run(cmd, env=None):
if testdir == "":
testdir = os.getcwd()
# We want to be in the root directory.
os.chdir(testdir + "/..")
print("\nWARNING: This script is for distro and package maintainers.")
print("It is for finding the optimal Karatsuba number.")
print("Though it only needs to be run once per release/platform,")
@ -116,7 +113,7 @@ def run(cmd, env=None):
except KeyError:
flags["CFLAGS"] = "-flto"
p = run([ "./configure.sh", "-O3" ], flags)
p = run([ "{}/../configure.sh".format(testdir), "-O3" ], flags)
if p.returncode != 0:
print("configure.sh returned an error ({}); exiting...".format(p.returncode))
sys.exit(p.returncode)
@ -161,7 +158,7 @@ def run(cmd, env=None):
# Configure and compile.
print("\nCompiling...\n")
p = run([ "./configure.sh", "-O3", "-k{}".format(i) ], config_env)
p = run([ "{}/../configure.sh".format(testdir), "-O3", "-k{}".format(i) ], config_env)
if p.returncode != 0:
print("configure.sh returned an error ({}); exiting...".format(p.returncode))

View File

@ -91,6 +91,8 @@ static void bc_args_redefine(const char *keyword) {
size_t i;
BC_SIG_ASSERT_LOCKED;
for (i = 0; i < bc_lex_kws_len; ++i) {
const BcLexKeyword *kw = bc_lex_kws + i;

View File

@ -158,6 +158,8 @@ void bc_lex_token(BcLex *l) {
// character of every identifier would be missing.
char c = l->buf[l->i++], c2;
BC_SIG_ASSERT_LOCKED;
// This is the workhorse of the lexer.
switch (c) {

View File

@ -79,6 +79,7 @@ static bool bc_parse_inst_isLeaf(BcInst t) {
* that can legally end a statement. In bc's case, it could be a newline, a
* semicolon, and a brace in certain cases.
* @param p The parser.
* @return True if the token is a legal delimiter.
*/
static bool bc_parse_isDelimiter(const BcParse *p) {
@ -127,6 +128,23 @@ static bool bc_parse_isDelimiter(const BcParse *p) {
return good;
}
/**
* Returns true if we are in top level of a function body. The POSIX grammar
* is defined such that anything is allowed after a function body, so we must
* use this function to detect that case when ending a function body.
* @param p The parser.
* @return True if we are in the top level of parsing a function body.
*/
static bool bc_parse_TopFunc(const BcParse *p) {
bool good = p->flags.len == 2;
uint16_t val = BC_PARSE_FLAG_BRACE | BC_PARSE_FLAG_FUNC_INNER;
val |= BC_PARSE_FLAG_FUNC;
return good && BC_PARSE_TOP_FLAG(p) == val;
}
/**
* Sets a previously defined exit label. What are labels? See the bc Parsing
* section of the Development manual (manuals/development.md).
@ -329,12 +347,8 @@ static void bc_parse_call(BcParse *p, const char *name, uint8_t flags) {
// not define it, it's a *runtime* error, not a parse error.
if (idx == BC_VEC_INVALID_IDX) {
BC_SIG_LOCK;
idx = bc_program_insertFunc(p->prog, name);
BC_SIG_UNLOCK;
assert(idx != BC_VEC_INVALID_IDX);
// Make sure that this pointer was not invalidated.
@ -359,15 +373,13 @@ static void bc_parse_name(BcParse *p, BcInst *type,
{
char *name;
BC_SIG_LOCK;
BC_SIG_ASSERT_LOCKED;
// We want a copy of the name since the lexer might overwrite its copy.
name = bc_vm_strdup(p->l.str.v);
BC_SETJMP_LOCKED(err);
BC_SIG_UNLOCK;
// We need the next token to see if it's just a variable or something more.
bc_lex_next(&p->l);
@ -431,9 +443,9 @@ static void bc_parse_name(BcParse *p, BcInst *type,
err:
// Need to make sure to unallocate the name.
BC_SIG_MAYLOCK;
free(name);
BC_LONGJMP_CONT;
BC_SIG_MAYLOCK;
}
/**
@ -887,7 +899,7 @@ static void bc_parse_endBody(BcParse *p, bool brace) {
bc_lex_next(&p->l);
// If the next token is not a delimiter, that is a problem.
if (BC_ERR(!bc_parse_isDelimiter(p)))
if (BC_ERR(!bc_parse_isDelimiter(p) && !bc_parse_TopFunc(p)))
bc_parse_err(p, BC_ERR_PARSE_TOKEN);
}
@ -1315,15 +1327,9 @@ static void bc_parse_func(BcParse *p) {
// Make sure the functions map and vector are synchronized.
assert(p->prog->fns.len == p->prog->fn_map.len);
// Must lock signals because vectors are changed, and the vector functions
// expect signals to be locked.
BC_SIG_LOCK;
// Insert the function by name into the map and vector.
idx = bc_program_insertFunc(p->prog, p->l.str.v);
BC_SIG_UNLOCK;
// Make sure the insert worked.
assert(idx);
@ -1753,13 +1759,21 @@ static void bc_parse_stmt(BcParse *p) {
// Make sure semicolons are eaten.
while (p->l.t == BC_LEX_SCOLON) bc_lex_next(&p->l);
// POSIX's grammar does not allow a function definition after a semicolon
// without a newline, so check specifically for that case and error if
// the POSIX standard flag is set.
if (p->l.last == BC_LEX_SCOLON && p->l.t == BC_LEX_KW_DEFINE && BC_IS_POSIX)
{
bc_parse_err(p, BC_ERR_POSIX_FUNC_AFTER_SEMICOLON);
}
}
void bc_parse_parse(BcParse *p) {
assert(p);
BC_SETJMP(exit);
BC_SETJMP_LOCKED(exit);
// We should not let an EOF get here unless some partial parse was not
// completed, in which case, it's the user's fault.
@ -1780,13 +1794,12 @@ void bc_parse_parse(BcParse *p) {
exit:
BC_SIG_MAYLOCK;
// We need to reset on error.
if (BC_ERR(((vm.status && vm.status != BC_STATUS_QUIT) || vm.sig)))
bc_parse_reset(p);
BC_LONGJMP_CONT;
BC_SIG_MAYLOCK;
}
/**

View File

@ -202,7 +202,7 @@ const uchar bc_err_ids[] = {
BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
#endif // BC_ENABLED
};
@ -273,6 +273,7 @@ const char* const bc_err_msgs[] = {
"POSIX does not allow comparison operators outside if statements or loops",
"POSIX requires 0 or 1 comparison operators per condition",
"POSIX requires all 3 parts of a for loop to be non-empty",
"POSIX requires a newline between a semicolon and a function definition",
#if BC_ENABLE_EXTRA_MATH
"POSIX does not allow exponential notation",
#else

View File

@ -157,6 +157,8 @@ void dc_lex_token(BcLex *l) {
char c = l->buf[l->i++], c2;
size_t i;
BC_SIG_ASSERT_LOCKED;
// If the last token was a command that needs a register, we need to parse a
// register, so do so.
for (i = 0; i < dc_lex_regs_len; ++i) {

View File

@ -302,7 +302,7 @@ void dc_parse_parse(BcParse *p) {
assert(p != NULL);
BC_SETJMP(exit);
BC_SETJMP_LOCKED(exit);
// If we have EOF, someone called this function one too many times.
// Otherwise, parse.
@ -311,11 +311,10 @@ void dc_parse_parse(BcParse *p) {
exit:
BC_SIG_MAYLOCK;
// Need to reset if there was an error.
if (BC_SIG_EXC) bc_parse_reset(p);
BC_LONGJMP_CONT;
BC_SIG_MAYLOCK;
}
#endif // DC_ENABLED

View File

@ -94,8 +94,12 @@ static BcStatus bc_file_output(int fd, const char *buf, size_t n) {
ssize_t written = write(fd, buf + bytes, n - bytes);
// Check for error and return, if any.
if (BC_ERR(written == -1))
if (BC_ERR(written == -1)) {
BC_SIG_TRYUNLOCK(lock);
return errno == EPIPE ? BC_STATUS_EOF : BC_STATUS_ERROR_FATAL;
}
bytes += (size_t) written;
}
@ -109,6 +113,8 @@ BcStatus bc_file_flushErr(BcFile *restrict f, BcFlushType type)
{
BcStatus s;
BC_SIG_ASSERT_LOCKED;
// If there is stuff to output...
if (f->len) {
@ -151,7 +157,12 @@ BcStatus bc_file_flushErr(BcFile *restrict f, BcFlushType type)
void bc_file_flush(BcFile *restrict f, BcFlushType type) {
BcStatus s = bc_file_flushErr(f, type);
BcStatus s;
sig_atomic_t lock;
BC_SIG_TRYLOCK(lock);
s = bc_file_flushErr(f, type);
// If we have an error...
if (BC_ERR(s)) {
@ -159,16 +170,23 @@ void bc_file_flush(BcFile *restrict f, BcFlushType type) {
// For EOF, set it and jump.
if (s == BC_STATUS_EOF) {
vm.status = (sig_atomic_t) s;
BC_SIG_TRYUNLOCK(lock);
BC_JMP;
}
// Blow up on fatal error. Okay, not blow up, just quit.
else bc_vm_fatalError(BC_ERR_FATAL_IO_ERR);
}
BC_SIG_TRYUNLOCK(lock);
}
void bc_file_write(BcFile *restrict f, BcFlushType type,
const char *buf, size_t n)
{
sig_atomic_t lock;
BC_SIG_TRYLOCK(lock);
// If we have enough to flush, do it.
if (n > f->cap - f->len) {
bc_file_flush(f, type);
@ -182,15 +200,22 @@ void bc_file_write(BcFile *restrict f, BcFlushType type,
memcpy(f->buf + f->len, buf, n);
f->len += n;
}
BC_SIG_TRYUNLOCK(lock);
}
void bc_file_printf(BcFile *restrict f, const char *fmt, ...)
{
va_list args;
sig_atomic_t lock;
BC_SIG_TRYLOCK(lock);
va_start(args, fmt);
bc_file_vprintf(f, fmt, args);
va_end(args);
BC_SIG_TRYUNLOCK(lock);
}
void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) {
@ -199,6 +224,8 @@ void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) {
const char *ptr = fmt;
char buf[BC_FILE_ULL_LENGTH];
BC_SIG_ASSERT_LOCKED;
// This is a poor man's printf(). While I could look up algorithms to make
// it as fast as possible, and should when I write the standard library for
// a new language, for bc, outputting is not the bottleneck. So we cheese it
@ -287,12 +314,18 @@ void bc_file_puts(BcFile *restrict f, BcFlushType type, const char *str) {
void bc_file_putchar(BcFile *restrict f, BcFlushType type, uchar c) {
sig_atomic_t lock;
BC_SIG_TRYLOCK(lock);
if (f->len == f->cap) bc_file_flush(f, type);
assert(f->len < f->cap);
f->buf[f->len] = (char) c;
f->len += 1;
BC_SIG_TRYUNLOCK(lock);
}
void bc_file_init(BcFile *f, int fd, char *buf, size_t cap) {

View File

@ -375,7 +375,7 @@ static ssize_t bc_history_read(char *buf, size_t n) {
ssize_t ret;
BC_SIG_LOCK;
BC_SIG_ASSERT_LOCKED;
#ifndef _WIN32
@ -396,8 +396,6 @@ static ssize_t bc_history_read(char *buf, size_t n) {
#endif // _WIN32
BC_SIG_UNLOCK;
return ret;
}
@ -416,8 +414,13 @@ static BcStatus bc_history_readCode(char *buf, size_t buf_len,
assert(buf_len >= 1);
BC_SIG_LOCK;
// Read a byte.
n = bc_history_read(buf, 1);
BC_SIG_UNLOCK;
if (BC_ERR(n <= 0)) goto err;
// Get the byte.
@ -431,24 +434,36 @@ static BcStatus bc_history_readCode(char *buf, size_t buf_len,
assert(buf_len >= 2);
BC_SIG_LOCK;
n = bc_history_read(buf + 1, 1);
BC_SIG_UNLOCK;
if (BC_ERR(n <= 0)) goto err;
}
else if ((byte & 0xF0) == 0xE0) {
assert(buf_len >= 3);
BC_SIG_LOCK;
n = bc_history_read(buf + 1, 2);
BC_SIG_UNLOCK;
if (BC_ERR(n <= 0)) goto err;
}
else if ((byte & 0xF8) == 0xF0) {
assert(buf_len >= 3);
BC_SIG_LOCK;
n = bc_history_read(buf + 1, 3);
BC_SIG_UNLOCK;
if (BC_ERR(n <= 0)) goto err;
}
else {
@ -606,6 +621,8 @@ static size_t bc_history_cursorPos(void) {
char *ptr, *ptr2;
size_t cols, rows, i;
BC_SIG_ASSERT_LOCKED;
// Report cursor location.
bc_file_write(&vm.fout, bc_flush_none, "\x1b[6n", 4);
bc_file_flush(&vm.fout, bc_flush_none);
@ -648,12 +665,8 @@ static size_t bc_history_columns(void) {
struct winsize ws;
int ret;
BC_SIG_LOCK;
ret = ioctl(vm.fout.fd, TIOCGWINSZ, &ws);
BC_SIG_UNLOCK;
if (BC_ERR(ret == -1 || !ws.ws_col)) {
// Calling ioctl() failed. Try to query the terminal itself.
@ -721,6 +734,8 @@ static void bc_history_refresh(BcHistory *h) {
char* buf = h->buf.v;
size_t colpos, len = BC_HIST_BUF_LEN(h), pos = h->pos, extras_len = 0;
BC_SIG_ASSERT_LOCKED;
bc_file_flush(&vm.fout, bc_flush_none);
// Get to the prompt column position from the left.
@ -783,6 +798,8 @@ static void bc_history_refresh(BcHistory *h) {
*/
static void bc_history_edit_insert(BcHistory *h, const char *cbuf, size_t clen)
{
BC_SIG_ASSERT_LOCKED;
bc_vec_grow(&h->buf, clen);
// If we are at the end of the line...
@ -836,6 +853,8 @@ static void bc_history_edit_insert(BcHistory *h, const char *cbuf, size_t clen)
*/
static void bc_history_edit_left(BcHistory *h) {
BC_SIG_ASSERT_LOCKED;
// Stop at the left end.
if (h->pos <= 0) return;
@ -850,6 +869,8 @@ static void bc_history_edit_left(BcHistory *h) {
*/
static void bc_history_edit_right(BcHistory *h) {
BC_SIG_ASSERT_LOCKED;
// Stop at the right end.
if (h->pos == BC_HIST_BUF_LEN(h)) return;
@ -866,6 +887,8 @@ static void bc_history_edit_wordEnd(BcHistory *h) {
size_t len = BC_HIST_BUF_LEN(h);
BC_SIG_ASSERT_LOCKED;
// Don't overflow.
if (!len || h->pos >= len) return;
@ -884,6 +907,8 @@ static void bc_history_edit_wordStart(BcHistory *h) {
size_t len = BC_HIST_BUF_LEN(h);
BC_SIG_ASSERT_LOCKED;
// Stop with no data.
if (!len) return;
@ -900,6 +925,8 @@ static void bc_history_edit_wordStart(BcHistory *h) {
*/
static void bc_history_edit_home(BcHistory *h) {
BC_SIG_ASSERT_LOCKED;
// Stop at the beginning.
if (!h->pos) return;
@ -914,6 +941,8 @@ static void bc_history_edit_home(BcHistory *h) {
*/
static void bc_history_edit_end(BcHistory *h) {
BC_SIG_ASSERT_LOCKED;
// Stop at the end of the line.
if (h->pos == BC_HIST_BUF_LEN(h)) return;
@ -932,11 +961,11 @@ static void bc_history_edit_next(BcHistory *h, bool dir) {
const char *dup, *str;
BC_SIG_ASSERT_LOCKED;
// Stop if there is no history.
if (h->history.len <= 1) return;
BC_SIG_LOCK;
// Duplicate the buffer.
if (h->buf.v[0]) dup = bc_vm_strdup(h->buf.v);
else dup = "";
@ -944,8 +973,6 @@ static void bc_history_edit_next(BcHistory *h, bool dir) {
// Update the current history entry before overwriting it with the next one.
bc_vec_replaceAt(&h->history, h->history.len - 1 - h->idx, &dup);
BC_SIG_UNLOCK;
// Show the new entry.
h->idx += (dir == BC_HIST_PREV ? 1 : SIZE_MAX);
@ -980,6 +1007,8 @@ static void bc_history_edit_delete(BcHistory *h) {
size_t chlen, len = BC_HIST_BUF_LEN(h);
BC_SIG_ASSERT_LOCKED;
// If there is no character, skip.
if (!len || h->pos >= len) return;
@ -1005,6 +1034,8 @@ static void bc_history_edit_backspace(BcHistory *h) {
size_t chlen, len = BC_HIST_BUF_LEN(h);
BC_SIG_ASSERT_LOCKED;
// If there are no characters, skip.
if (!h->pos || !len) return;
@ -1031,6 +1062,8 @@ static void bc_history_edit_deletePrevWord(BcHistory *h) {
size_t diff, old_pos = h->pos;
BC_SIG_ASSERT_LOCKED;
// If at the beginning of the line, skip.
if (!old_pos) return;
@ -1059,6 +1092,8 @@ static void bc_history_edit_deleteNextWord(BcHistory *h) {
size_t next_end = h->pos, len = BC_HIST_BUF_LEN(h);
BC_SIG_ASSERT_LOCKED;
// If at the end of the line, skip.
if (next_end == len) return;
@ -1084,6 +1119,8 @@ static void bc_history_swap(BcHistory *h) {
size_t pcl, ncl;
char auxb[5];
BC_SIG_ASSERT_LOCKED;
// Get the length of the previous and next characters.
pcl = bc_history_prevLen(h->buf.v, h->pos);
ncl = bc_history_nextLen(h->buf.v, BC_HIST_BUF_LEN(h), h->pos, NULL);
@ -1126,6 +1163,8 @@ static void bc_history_escape(BcHistory *h) {
char c, seq[3];
BC_SIG_ASSERT_LOCKED;
// Read a character into seq.
if (BC_ERR(BC_HIST_READ(seq, 1))) return;
@ -1274,6 +1313,8 @@ static void bc_history_escape(BcHistory *h) {
*/
static void bc_history_add(BcHistory *h, char *line) {
BC_SIG_ASSERT_LOCKED;
// If there is something already there...
if (h->history.len) {
@ -1282,13 +1323,7 @@ static void bc_history_add(BcHistory *h, char *line) {
// Check for, and discard, duplicates.
if (!strcmp(s, line)) {
BC_SIG_LOCK;
free(line);
BC_SIG_UNLOCK;
return;
}
}
@ -1303,6 +1338,8 @@ static void bc_history_add(BcHistory *h, char *line) {
*/
static void bc_history_add_empty(BcHistory *h) {
BC_SIG_ASSERT_LOCKED;
const char *line = "";
// If there is something already there...
@ -1324,6 +1361,8 @@ static void bc_history_add_empty(BcHistory *h) {
*/
static void bc_history_reset(BcHistory *h) {
BC_SIG_ASSERT_LOCKED;
h->oldcolpos = h->pos = h->idx = 0;
h->cols = bc_history_columns();
@ -1345,6 +1384,8 @@ static void bc_history_printCtrl(BcHistory *h, unsigned int c) {
char str[3] = "^A";
const char newline[2] = "\n";
BC_SIG_ASSERT_LOCKED;
// Set the correct character.
str[1] = (char) (c + 'A' - BC_ACTION_CTRL_A);
@ -1378,6 +1419,8 @@ static void bc_history_printCtrl(BcHistory *h, unsigned int c) {
*/
static BcStatus bc_history_edit(BcHistory *h, const char *prompt) {
BC_SIG_LOCK;
bc_history_reset(h);
// Don't write the saved output the first time. This is because it has
@ -1404,10 +1447,14 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) {
unsigned int c = 0;
size_t nread = 0;
BC_SIG_UNLOCK;
// Read a code.
s = bc_history_readCode(cbuf, sizeof(cbuf), &c, &nread);
if (BC_ERR(s)) return s;
BC_SIG_LOCK;
switch (c) {
case BC_ACTION_LINE_FEED:
@ -1415,6 +1462,7 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) {
{
// Return the line.
bc_vec_pop(&h->history);
BC_SIG_UNLOCK;
return s;
}
@ -1434,6 +1482,7 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) {
// Quit if the user wants it.
if (!BC_SIGINT) {
vm.status = BC_STATUS_QUIT;
BC_SIG_UNLOCK;
BC_JMP;
}
@ -1460,6 +1509,7 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) {
case BC_ACTION_CTRL_D:
{
bc_history_printCtrl(h, c);
BC_SIG_UNLOCK;
return BC_STATUS_EOF;
}
#endif // _WIN32
@ -1565,6 +1615,7 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) {
bc_history_raise(h, SIGQUIT);
#else // _WIN32
vm.status = BC_STATUS_QUIT;
BC_SIG_UNLOCK;
BC_JMP;
#endif // _WIN32
}
@ -1575,6 +1626,8 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) {
}
}
BC_SIG_UNLOCK;
return BC_STATUS_SUCCESS;
}
@ -1611,22 +1664,22 @@ BcStatus bc_history_line(BcHistory *h, BcVec *vec, const char *prompt) {
bc_file_write(&vm.fout, bc_flush_none, "\n", 1);
bc_file_flush(&vm.fout, bc_flush_none);
BC_SIG_LOCK;
// If we actually have data...
if (h->buf.v[0]) {
BC_SIG_LOCK;
// Duplicate it.
line = bc_vm_strdup(h->buf.v);
BC_SIG_UNLOCK;
// Store it.
bc_history_add(h, line);
}
// Add an empty string.
else bc_history_add_empty(h);
BC_SIG_UNLOCK;
// Concatenate the line to the return vector.
bc_vec_concat(vec, h->buf.v);
bc_vec_concat(vec, "\n");

View File

@ -258,6 +258,8 @@ void bc_lex_file(BcLex *l, const char *file) {
void bc_lex_next(BcLex *l) {
BC_SIG_ASSERT_LOCKED;
assert(l != NULL);
l->last = l->t;
@ -294,7 +296,15 @@ static void bc_lex_fixText(BcLex *l, const char *text, size_t len) {
bool bc_lex_readLine(BcLex *l) {
bool good = bc_vm_readLine(false);
bool good;
// These are reversed because they should be already locked, but
// bc_vm_readLine() needs them to be unlocked.
BC_SIG_UNLOCK;
good = bc_vm_readLine(false);
BC_SIG_LOCK;
bc_lex_fixText(l, vm.buffer.v, vm.buffer.len - 1);
@ -302,10 +312,15 @@ bool bc_lex_readLine(BcLex *l) {
}
void bc_lex_text(BcLex *l, const char *text, bool is_stdin) {
BC_SIG_ASSERT_LOCKED;
assert(l != NULL && text != NULL);
bc_lex_fixText(l, text, strlen(text));
l->i = 0;
l->t = l->last = BC_LEX_INVALID;
l->is_stdin = is_stdin;
bc_lex_next(l);
}

View File

@ -77,9 +77,14 @@ BclError bcl_init(void) {
BclError e = BCL_ERROR_NONE;
BC_SIG_LOCK;
vm.refs += 1;
if (vm.refs > 1) return e;
if (vm.refs > 1) {
BC_SIG_UNLOCK;
return e;
}
// Setting these to NULL ensures that if an error occurs, we only free what
// is necessary.
@ -89,8 +94,6 @@ BclError bcl_init(void) {
vm.abrt = false;
BC_SIG_LOCK;
// The jmp_bufs always has to be initialized first.
bc_vec_init(&vm.jmp_bufs, sizeof(sigjmp_buf), BC_DTOR_NONE);
@ -146,11 +149,14 @@ void bcl_free(void) {
size_t i;
BC_SIG_LOCK;
vm.refs -= 1;
if (vm.refs) return;
BC_SIG_LOCK;
if (vm.refs) {
BC_SIG_UNLOCK;
return;
}
bc_rand_free(&vm.rng);
bc_vec_free(&vm.out);

View File

@ -235,7 +235,7 @@ static bool bc_opt_longoptsMatch(const char *name, const char *option) {
// Can never match a NULL name.
if (name == NULL) return false;
// Loop through
// Loop through.
for (; *a && *n && *a != '='; ++a, ++n) {
if (*a != *n) return false;
}

View File

@ -70,15 +70,11 @@ void bc_parse_addString(BcParse *p) {
size_t idx;
BC_SIG_LOCK;
idx = bc_program_addString(p->prog, p->l.str.v, p->fidx);
// Push the string info.
bc_parse_update(p, BC_INST_STR, p->fidx);
bc_parse_pushIndex(p, idx);
BC_SIG_UNLOCK;
}
static void bc_parse_addNum(BcParse *p, const char *string) {
@ -88,6 +84,8 @@ static void bc_parse_addNum(BcParse *p, const char *string) {
BcConst *c;
BcVec *slabs;
BC_SIG_ASSERT_LOCKED;
// Special case 0.
if (bc_parse_zero[0] == string[0] && bc_parse_zero[1] == string[1]) {
bc_parse_push(p, BC_INST_ZERO);
@ -103,8 +101,6 @@ static void bc_parse_addNum(BcParse *p, const char *string) {
// Get the index.
idx = consts->len;
BC_SIG_LOCK;
// Get the right slab.
slabs = p->fidx == BC_PROG_MAIN || p->fidx == BC_PROG_READ ?
&vm.main_const_slab : &vm.other_slabs;
@ -120,8 +116,6 @@ static void bc_parse_addNum(BcParse *p, const char *string) {
bc_num_clear(&c->num);
bc_parse_update(p, BC_INST_NUM, idx);
BC_SIG_UNLOCK;
}
void bc_parse_number(BcParse *p) {
@ -158,9 +152,13 @@ void bc_parse_number(BcParse *p) {
void bc_parse_text(BcParse *p, const char *text, bool is_stdin) {
BC_SIG_LOCK;
// Make sure the pointer isn't invalidated.
p->func = bc_vec_item(&p->prog->fns, p->fidx);
bc_lex_text(&p->l, text, is_stdin);
BC_SIG_UNLOCK;
}
void bc_parse_reset(BcParse *p) {

View File

@ -55,6 +55,7 @@
* @param f The new function.
*/
static inline void bc_program_setVecs(BcProgram *p, BcFunc *f) {
BC_SIG_ASSERT_LOCKED;
p->consts = &f->consts;
p->strs = &f->strs;
}
@ -152,6 +153,8 @@ static void bc_program_popGlobals(BcProgram *p, bool reset) {
size_t i;
BC_SIG_ASSERT_LOCKED;
for (i = 0; i < BC_PROG_GLOBALS_LEN; ++i) {
BcVec *v = p->globals_v + i;
bc_vec_npop(v, reset ? v->len - 1 : 1);
@ -238,12 +241,12 @@ size_t bc_program_search(BcProgram *p, const char *id, bool var) {
BcVec *v, *map;
size_t i;
BC_SIG_ASSERT_LOCKED;
// Grab the right vector and map.
v = var ? &p->vars : &p->arrs;
map = var ? &p->var_map : &p->arr_map;
BC_SIG_LOCK;
// We do an insert because the variable might not exist yet. This is because
// the parser calls this function. If the insert succeeds, we create a stack
// for the variable/array. But regardless, bc_map_insert() gives us the
@ -253,8 +256,6 @@ size_t bc_program_search(BcProgram *p, const char *id, bool var) {
bc_array_init(temp, var);
}
BC_SIG_UNLOCK;
return ((BcId*) bc_vec_item(map, i))->idx;
}
@ -711,7 +712,9 @@ static void bc_program_read(BcProgram *p) {
// Parse *one* expression.
bc_parse_text(&vm.read_prs, vm.read_buf.v, false);
BC_SIG_LOCK;
vm.expr(&vm.read_prs, BC_PARSE_NOREAD | BC_PARSE_NEEDVAL);
BC_SIG_UNLOCK;
// We *must* have a valid expression. A semicolon cannot end an expression,
// although EOF can.
@ -736,6 +739,9 @@ static void bc_program_read(BcProgram *p) {
// We want a return instruction to simplify things.
bc_vec_pushByte(&f->code, vm.read_ret);
// This lock is here to make sure dc's tail calls are the same length.
BC_SIG_LOCK;
bc_vec_push(&p->stack, &ip);
#if DC_ENABLED
@ -784,6 +790,9 @@ static void bc_program_printChars(const char *str) {
const char *nl;
size_t len = vm.nchars + strlen(str);
sig_atomic_t lock;
BC_SIG_TRYLOCK(lock);
bc_file_puts(&vm.fout, bc_flush_save, str);
@ -794,6 +803,8 @@ static void bc_program_printChars(const char *str) {
if (nl != NULL) len = strlen(nl + 1);
vm.nchars = len > UINT16_MAX ? UINT16_MAX : (uint16_t) len;
BC_SIG_TRYUNLOCK(lock);
}
/**
@ -830,7 +841,11 @@ static void bc_program_printString(const char *restrict str) {
if (ptr != NULL) {
// We need to specially handle a newline.
if (c == 'n') vm.nchars = UINT16_MAX;
if (c == 'n') {
BC_SIG_LOCK;
vm.nchars = UINT16_MAX;
BC_SIG_UNLOCK;
}
// Grab the actual character.
c = bc_program_esc_seqs[(size_t) (ptr - bc_program_esc_chars)];
@ -1770,6 +1785,8 @@ static void bc_program_return(BcProgram *p, uchar inst) {
bc_vec_pop(v);
}
BC_SIG_LOCK;
// When we retire, pop all of the unused results.
bc_program_retire(p, 1, nresults);
@ -1778,6 +1795,8 @@ static void bc_program_return(BcProgram *p, uchar inst) {
// Pop the stack. This is what causes the function to actually "return."
bc_vec_pop(&p->stack);
BC_SIG_UNLOCK;
}
#endif // BC_ENABLED
@ -2184,8 +2203,10 @@ static void bc_program_nquit(BcProgram *p, uchar inst) {
// because these are for tail calls. That means that any executions that
// we would not have quit in that position on the stack would have quit
// anyway.
BC_SIG_LOCK;
bc_vec_npop(&p->stack, i);
bc_vec_npop(&p->tail_calls, i);
BC_SIG_UNLOCK;
}
}
@ -2311,9 +2332,9 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code,
// Parse.
bc_parse_text(&vm.read_prs, str, false);
vm.expr(&vm.read_prs, BC_PARSE_NOCALL);
BC_SIG_LOCK;
vm.expr(&vm.read_prs, BC_PARSE_NOCALL);
BC_UNSETJMP;
@ -2329,6 +2350,8 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code,
ip.len = p->results.len;
ip.func = fidx;
BC_SIG_LOCK;
// Pop the operand.
bc_vec_pop(&p->results);
@ -2352,6 +2375,8 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code,
// Push the new function onto the execution stack and return.
bc_vec_push(&p->stack, &ip);
BC_SIG_UNLOCK;
return;
err:
@ -2678,7 +2703,9 @@ void bc_program_exec(BcProgram *p) {
code = func->code.v;
// Ensure the pointers are correct.
BC_SIG_LOCK;
bc_program_setVecs(p, func);
BC_SIG_UNLOCK;
#if !BC_HAS_COMPUTED_GOTO
@ -2759,10 +2786,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@ -2792,10 +2821,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@ -2824,10 +2855,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@ -2909,10 +2942,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@ -3086,10 +3121,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@ -3103,10 +3140,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}
@ -3179,10 +3218,12 @@ void bc_program_exec(BcProgram *p) {
// Because we changed the execution stack and where we are
// executing, we have to update all of this.
BC_SIG_LOCK;
ip = bc_vec_top(&p->stack);
func = bc_vec_item(&p->fns, ip->func);
code = func->code.v;
bc_program_setVecs(p, func);
BC_SIG_UNLOCK;
BC_PROG_JUMP(inst, code, ip);
}

View File

@ -461,16 +461,21 @@ BcRand bc_rand_int(BcRNG *r) {
// Get the actual PRNG.
BcRNGData *rng = bc_vec_top(&r->v);
BcRand res;
// Make sure the PRNG is seeded.
if (BC_ERR(BC_RAND_ZERO(rng))) bc_rand_srand(rng);
// This is the important part of the PRNG. This is the stuff from PCG,
// including the return statement.
BC_SIG_LOCK;
// This is the important part of the PRNG. This is the stuff from PCG.
bc_rand_step(rng);
bc_rand_propagate(r, rng);
res = bc_rand_output(rng);
return bc_rand_output(rng);
BC_SIG_UNLOCK;
return res;
}
BcRand bc_rand_bounded(BcRNG *r, BcRand bound) {

View File

@ -196,12 +196,16 @@ BcStatus bc_read_chars(BcVec *vec, const char *prompt) {
return BC_STATUS_EOF;
}
BC_SIG_LOCK;
// Add to the buffer.
vm.buf_len += (size_t) r;
vm.buf[vm.buf_len] = '\0';
// Read from the buffer.
done = bc_read_buf(vec, vm.buf, &vm.buf_len);
BC_SIG_UNLOCK;
}
// Terminate the string.

View File

@ -186,9 +186,11 @@ void bc_vm_info(const char* const help) {
"disabled";
const char* const prompt = BC_DEFAULT_PROMPT ? "enabled" :
"disabled";
const char* const expr = BC_DEFAULT_EXPR_EXIT ? "to exit" :
"to not exit";
bc_file_printf(&vm.fout, help, vm.name, vm.name, BC_VERSION,
BC_BUILD_TYPE, banner, sigint, tty, prompt);
BC_BUILD_TYPE, banner, sigint, tty, prompt, expr);
}
#endif // BC_ENABLED
@ -201,9 +203,11 @@ void bc_vm_info(const char* const help) {
"disabled";
const char* const prompt = DC_DEFAULT_PROMPT ? "enabled" :
"disabled";
const char* const expr = DC_DEFAULT_EXPR_EXIT ? "to exit" :
"to not exit";
bc_file_printf(&vm.fout, help, vm.name, vm.name, BC_VERSION,
BC_BUILD_TYPE, sigint, tty, prompt);
BC_BUILD_TYPE, sigint, tty, prompt, expr);
}
#endif // DC_ENABLED
}
@ -552,6 +556,8 @@ void bc_vm_shutdown(void) {
void bc_vm_addTemp(BcDig *num) {
BC_SIG_ASSERT_LOCKED;
// If we don't have room, just free.
if (vm.temps_len == BC_VM_MAX_TEMPS) free(num);
else {
@ -563,8 +569,13 @@ void bc_vm_addTemp(BcDig *num) {
}
BcDig* bc_vm_takeTemp(void) {
BC_SIG_ASSERT_LOCKED;
if (!vm.temps_len) return NULL;
vm.temps_len -= 1;
return temps_buf[vm.temps_len];
}
@ -660,8 +671,9 @@ char* bc_vm_strdup(const char *str) {
void bc_vm_printf(const char *fmt, ...) {
va_list args;
sig_atomic_t lock;
BC_SIG_LOCK;
BC_SIG_TRYLOCK(lock);
va_start(args, fmt);
bc_file_vprintf(&vm.fout, fmt, args);
@ -669,7 +681,7 @@ void bc_vm_printf(const char *fmt, ...) {
vm.nchars = 0;
BC_SIG_UNLOCK;
BC_SIG_TRYUNLOCK(lock);
}
#endif // !BC_ENABLE_LIBRARY
@ -745,6 +757,8 @@ static void bc_vm_clean(void) {
BcInstPtr *ip = bc_vec_item(&vm.prog.stack, 0);
bool good = ((vm.status && vm.status != BC_STATUS_QUIT) || vm.sig);
BC_SIG_ASSERT_LOCKED;
// If all is good, go ahead and reset.
if (good) bc_program_reset(&vm.prog);
@ -816,6 +830,8 @@ static void bc_vm_process(const char *text, bool is_stdin) {
do {
BC_SIG_LOCK;
#if BC_ENABLED
// If the first token is the keyword define, then we need to do this
// specially because bc thinks it may not be able to parse.
@ -825,6 +841,8 @@ static void bc_vm_process(const char *text, bool is_stdin) {
// Parse it all.
while (BC_PARSE_CAN_PARSE(vm.prs)) vm.parse(&vm.prs);
BC_SIG_UNLOCK;
// Execute if possible.
if(BC_IS_DC || !BC_PARSE_NO_EXEC(&vm.prs)) bc_program_exec(&vm.prog);
@ -901,6 +919,8 @@ bool bc_vm_readLine(bool clear) {
BcStatus s;
bool good;
BC_SIG_ASSERT_NOT_LOCKED;
// Clear the buffer if desired.
if (clear) bc_vec_empty(&vm.buffer);
@ -969,7 +989,11 @@ static void bc_vm_stdin(void) {
bc_vm_process(vm.buffer.v, true);
if (vm.eof) break;
else bc_vm_clean();
else {
BC_SIG_LOCK;
bc_vm_clean();
BC_SIG_UNLOCK;
}
}
#if BC_ENABLED
@ -1022,7 +1046,11 @@ static void bc_vm_load(const char *name, const char *text) {
bc_lex_file(&vm.prs.l, name);
bc_parse_text(&vm.prs, text, false);
BC_SIG_LOCK;
while (vm.prs.l.t != BC_LEX_EOF) vm.parse(&vm.prs);
BC_SIG_UNLOCK;
}
#endif // BC_ENABLED
@ -1172,7 +1200,7 @@ static void bc_vm_exec(void) {
BC_SIG_UNLOCK;
// Sometimes, executing expressions means we need to quit.
if (!vm.no_exprs && vm.exit_exprs) return;
if (!vm.no_exprs && vm.exit_exprs && BC_EXPR_EXIT) return;
}
// Process files.
@ -1194,9 +1222,7 @@ static void bc_vm_exec(void) {
// We need to keep tty if history is enabled, and we need to keep rpath for
// the times when we read from /dev/urandom.
if (BC_TTY && !vm.history.badTerm) {
bc_pledge(bc_pledge_end_history, NULL);
}
if (BC_TTY && !vm.history.badTerm) bc_pledge(bc_pledge_end_history, NULL);
else
#endif // BC_ENABLE_HISTORY
{
@ -1233,6 +1259,8 @@ void bc_vm_boot(int argc, char *argv[]) {
bool tty;
const char* const env_len = BC_IS_BC ? "BC_LINE_LENGTH" : "DC_LINE_LENGTH";
const char* const env_args = BC_IS_BC ? "BC_ENV_ARGS" : "DC_ENV_ARGS";
const char* const env_exit = BC_IS_BC ? "BC_EXPR_EXIT" : "DC_EXPR_EXIT";
int env_exit_def = BC_IS_BC ? BC_DEFAULT_EXPR_EXIT : DC_DEFAULT_EXPR_EXIT;
// We need to know which of stdin, stdout, and stderr are tty's.
ttyin = isatty(STDIN_FILENO);
@ -1269,6 +1297,8 @@ void bc_vm_boot(int argc, char *argv[]) {
// Set the line length by environment variable.
vm.line_len = (uint16_t) bc_vm_envLen(env_len);
bc_vm_setenvFlag(env_exit, env_exit_def, BC_FLAG_EXPR_EXIT);
// Clear the files and expressions vectors, just in case. This marks them as
// *not* allocated.
bc_vec_clear(&vm.files);
@ -1289,26 +1319,22 @@ void bc_vm_boot(int argc, char *argv[]) {
bc_program_init(&vm.prog);
bc_parse_init(&vm.prs, &vm.prog, BC_PROG_MAIN);
#if BC_ENABLED
// bc checks this environment variable to see if it should run in standard
// mode.
if (BC_IS_BC) {
char* var = bc_vm_getenv("POSIXLY_CORRECT");
vm.flags |= BC_FLAG_S * (var != NULL);
bc_vm_getenvFree(var);
}
#endif // BC_ENABLED
// Set defaults.
vm.flags |= BC_TTY ? BC_FLAG_P | BC_FLAG_R : 0;
vm.flags |= BC_I ? BC_FLAG_Q : 0;
#if BC_ENABLED
if (BC_IS_BC && BC_I) {
if (BC_IS_BC) {
// bc checks this environment variable to see if it should run in
// standard mode.
char* var = bc_vm_getenv("POSIXLY_CORRECT");
vm.flags |= BC_FLAG_S * (var != NULL);
bc_vm_getenvFree(var);
// Set whether we print the banner or not.
bc_vm_setenvFlag("BC_BANNER", BC_DEFAULT_BANNER, BC_FLAG_Q);
if (BC_I) bc_vm_setenvFlag("BC_BANNER", BC_DEFAULT_BANNER, BC_FLAG_Q);
}
#endif // BC_ENABLED
@ -1349,9 +1375,7 @@ void bc_vm_boot(int argc, char *argv[]) {
#if BC_ENABLED
// Disable global stacks in POSIX mode.
if (BC_IS_POSIX) vm.flags &= ~(BC_FLAG_G);
#endif // BC_ENABLED
#if BC_ENABLED
// Print the banner if allowed. We have to be in bc, in interactive mode,
// and not be quieted by command-line option or environment variable.
if (BC_IS_BC && BC_I && (vm.flags & BC_FLAG_Q)) {

View File

@ -43,6 +43,7 @@ misc4
misc5
misc6
misc7
misc8
void
rand
recursive_arrays

View File

@ -0,0 +1,8 @@
define a(){
return 5
}define b(){
return 6
}
24
a()
b()

View File

@ -0,0 +1,3 @@
24
5
6

View File

@ -7,6 +7,7 @@ halt
define x(e) { return 0; }
define x(e) { return 4*(e+e); }
define x(e) { return (e+e)*4; }
define a() { return (5); };define b() { return (6); }
limits
.
if (q!=0) { x=3; } else { x=4; }

View File

@ -50,7 +50,6 @@ else
bc="$testdir/../../bin/bc"
fi
#
out1="$outputdir/bc_outputs/bc_timeconst.txt"
out2="$outputdir/bc_outputs/bc_timeconst_results.txt"

View File

@ -253,7 +253,7 @@ def test_sigint_sigquit(exe, args, env):
send(child, "\t")
expect(child, " ")
send(child, "\x03")
send(child, "\x1c")
# send(child, "\x1c")
wait(child)
except pexpect.TIMEOUT:
traceback.print_tb(sys.exc_info()[2])
@ -1044,6 +1044,7 @@ def test_dc3(exe, args, env):
test_dc_utf8_1,
test_dc_utf8_2,
test_dc_utf8_3,
test_dc_utf8_4,
test_sigint_sigquit,
test_eof,
test_sigint,

View File

@ -92,7 +92,7 @@ for i in $(seq "$st" "$idx"); do
printf 'Running %s history test %d...' "$d" "$i"
for j in $(seq 1 3); do
for j in $(seq 1 5); do
"$py" "$testdir/history.py" "$d" "$i" "$exe" "$@"
err="$?"

View File

@ -102,7 +102,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;BC_DEFAULT_EXPR_EXIT=1;DC_DEFAULT_EXPR_EXIT=1;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ConformanceMode>true</ConformanceMode>
@ -123,7 +123,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;BC_DEFAULT_EXPR_EXIT=1;DC_DEFAULT_EXPR_EXIT=1;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<ConformanceMode>true</ConformanceMode>
@ -144,7 +144,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;BC_DEFAULT_EXPR_EXIT=1;DC_DEFAULT_EXPR_EXIT=1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<ConformanceMode>true</ConformanceMode>
@ -164,7 +164,7 @@
<WarningLevel>Level3</WarningLevel>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;BUILD_TYPE=HN;BC_DEFAULT_BANNER=1;BC_DEFAULT_SIGINT_RESET=0;DC_DEFAULT_SIGINT_RESET=0;BC_DEFAULT_TTY_MODE=1;DC_DEFAULT_TTY_MODE=1;BC_DEFAULT_PROMPT=1;DC_DEFAULT_PROMPT=1;BC_DEFAULT_EXPR_EXIT=1;DC_DEFAULT_EXPR_EXIT=1;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>