From 23aff1240891b4ba4bb000345824ca0b87b9b3e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20E=C3=9Fer?= Date: Tue, 30 Nov 2021 18:26:22 +0100 Subject: [PATCH 1/2] vendor/bc: import release 5.2.0 This version is imported only for documentary purposes since it does not contain any changes that are relevant for the FreeBSD base system. --- Makefile.in | 204 +++++++++++++++++++++++----------------- NEWS.md | 14 +++ README.md | 60 ++++++++---- bcl.pc.in | 8 ++ configure.sh | 196 +++++++++++++++++++++++++++++--------- gen/bc_help.txt | 7 ++ gen/dc_help.txt | 7 ++ include/status.h | 8 ++ include/version.h | 2 +- include/vm.h | 6 ++ manuals/bc/A.1 | 13 +++ manuals/bc/A.1.md | 11 +++ manuals/bc/E.1 | 13 +++ manuals/bc/E.1.md | 11 +++ manuals/bc/EH.1 | 13 +++ manuals/bc/EH.1.md | 11 +++ manuals/bc/EHN.1 | 13 +++ manuals/bc/EHN.1.md | 11 +++ manuals/bc/EN.1 | 13 +++ manuals/bc/EN.1.md | 11 +++ manuals/bc/H.1 | 13 +++ manuals/bc/H.1.md | 11 +++ manuals/bc/HN.1 | 13 +++ manuals/bc/HN.1.md | 11 +++ manuals/bc/N.1 | 13 +++ manuals/bc/N.1.md | 11 +++ manuals/build.md | 17 ++++ manuals/dc/A.1 | 13 +++ manuals/dc/A.1.md | 11 +++ manuals/dc/E.1 | 13 +++ manuals/dc/E.1.md | 11 +++ manuals/dc/EH.1 | 13 +++ manuals/dc/EH.1.md | 11 +++ manuals/dc/EHN.1 | 13 +++ manuals/dc/EHN.1.md | 11 +++ manuals/dc/EN.1 | 13 +++ manuals/dc/EN.1.md | 11 +++ manuals/dc/H.1 | 13 +++ manuals/dc/H.1.md | 11 +++ manuals/dc/HN.1 | 13 +++ manuals/dc/HN.1.md | 11 +++ manuals/dc/N.1 | 13 +++ manuals/dc/N.1.md | 11 +++ scripts/exec-install.sh | 9 +- scripts/karatsuba.py | 7 +- src/args.c | 2 + src/bc_lex.c | 2 + src/bc_parse.c | 21 +---- src/dc_lex.c | 2 + src/dc_parse.c | 5 +- src/file.c | 37 +++++++- src/history.c | 95 ++++++++++++++----- src/lex.c | 17 +++- src/library.c | 18 ++-- src/opt.c | 2 +- src/parse.c | 14 ++- src/program.c | 53 +++++++++-- src/rand.c | 11 ++- src/read.c | 4 + src/vm.c | 74 ++++++++++----- tests/bc/timeconst.sh | 1 - tests/history.py | 3 +- tests/history.sh | 2 +- vs/bc.vcxproj | 8 +- 64 files changed, 1039 insertions(+), 261 deletions(-) create mode 100644 bcl.pc.in diff --git a/Makefile.in b/Makefile.in index 3d6780d6ac95..b9136a57aa92 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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) diff --git a/NEWS.md b/NEWS.md index 5251096d9f2a..fa2df6749783 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,19 @@ # News +## 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 diff --git a/README.md b/README.md index c46d66b7e3ea..259ab923bfc4 100644 --- a/README.md +++ b/README.md @@ -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= bc.sln +msbuild -property:Configuration= vs/bc.sln ``` where `` is either one of `Debug` or `Release`. +On Windows, the calculators are built as `vs/bin///bc.exe` and +`vs/bin///dc.exe`, where `` can be either `Win32` or +`x64`, and `` 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= bcl.sln +msbuild -property:Configuration= vs/bcl.sln ``` -where `` is either one of `Debug` or `Release`. +where `` is either one of `Debug`, `ReleaseMD`, or `ReleaseMT`. + +On Windows, the library is built as `vs/lib///bcl.lib`, where +`` can be either `Win32` or `x64`, and `` 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 diff --git a/bcl.pc.in b/bcl.pc.in new file mode 100644 index 000000000000..f440eeca950f --- /dev/null +++ b/bcl.pc.in @@ -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 diff --git a/configure.sh b/configure.sh index de1339780073..8a6a7817fd2a 100755 --- a/configure.sh +++ b/configure.sh @@ -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. @@ -205,6 +205,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 +293,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 +389,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 +433,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 +448,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 +467,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 +497,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 +543,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 +597,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 +625,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 +689,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 +981,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 +1034,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 +1191,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 +1253,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 +1276,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 +1337,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 +1370,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 +1385,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 +1461,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 +1534,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 +1571,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 +1588,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 +1613,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 +1682,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 +1733,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 +1752,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 diff --git a/gen/bc_help.txt b/gen/bc_help.txt index 9ba34c606481..36329b1d7aaf 100644 --- a/gen/bc_help.txt +++ b/gen/bc_help.txt @@ -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. diff --git a/gen/dc_help.txt b/gen/dc_help.txt index 4cf10826cd7f..a0f275b60b64 100644 --- a/gen/dc_help.txt +++ b/gen/dc_help.txt @@ -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. diff --git a/include/status.h b/include/status.h index 662f2b89c04d..3a23b09dc873 100644 --- a/include/status.h +++ b/include/status.h @@ -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 { diff --git a/include/version.h b/include/version.h index 72500c8e3f28..296dbc79b547 100644 --- a/include/version.h +++ b/include/version.h @@ -37,6 +37,6 @@ #define BC_VERSION_H /// The current version. -#define VERSION 5.1.1 +#define VERSION 5.2.0 #endif // BC_VERSION_H diff --git a/include/vm.h b/include/vm.h index bbc5e57e2ac8..d6f698fb1e6d 100644 --- a/include/vm.h +++ b/include/vm.h @@ -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. diff --git a/manuals/bc/A.1 b/manuals/bc/A.1 index bf6c9108456b..038932d52ada 100644 --- a/manuals/bc/A.1 +++ b/manuals/bc/A.1 @@ -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: diff --git a/manuals/bc/A.1.md b/manuals/bc/A.1.md index e773d967284c..112e98078cf0 100644 --- a/manuals/bc/A.1.md +++ b/manuals/bc/A.1.md @@ -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: diff --git a/manuals/bc/E.1 b/manuals/bc/E.1 index bb563f5c96fc..6ee1e063ebde 100644 --- a/manuals/bc/E.1 +++ b/manuals/bc/E.1 @@ -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: diff --git a/manuals/bc/E.1.md b/manuals/bc/E.1.md index 63367e436cc8..ba6e44c248c2 100644 --- a/manuals/bc/E.1.md +++ b/manuals/bc/E.1.md @@ -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: diff --git a/manuals/bc/EH.1 b/manuals/bc/EH.1 index 0bdfaa9fe14b..4509583a0141 100644 --- a/manuals/bc/EH.1 +++ b/manuals/bc/EH.1 @@ -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: diff --git a/manuals/bc/EH.1.md b/manuals/bc/EH.1.md index 044330b7fe0a..2178c375cb92 100644 --- a/manuals/bc/EH.1.md +++ b/manuals/bc/EH.1.md @@ -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: diff --git a/manuals/bc/EHN.1 b/manuals/bc/EHN.1 index f0519898ad7e..6b49f3651d5a 100644 --- a/manuals/bc/EHN.1 +++ b/manuals/bc/EHN.1 @@ -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: diff --git a/manuals/bc/EHN.1.md b/manuals/bc/EHN.1.md index 25543500eea7..3b60d3d0251b 100644 --- a/manuals/bc/EHN.1.md +++ b/manuals/bc/EHN.1.md @@ -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: diff --git a/manuals/bc/EN.1 b/manuals/bc/EN.1 index 192dccfea2fc..c4704807fac6 100644 --- a/manuals/bc/EN.1 +++ b/manuals/bc/EN.1 @@ -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: diff --git a/manuals/bc/EN.1.md b/manuals/bc/EN.1.md index e77d64cd7a56..13ad5f8b570a 100644 --- a/manuals/bc/EN.1.md +++ b/manuals/bc/EN.1.md @@ -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: diff --git a/manuals/bc/H.1 b/manuals/bc/H.1 index 5f290f12ae32..f6d555943367 100644 --- a/manuals/bc/H.1 +++ b/manuals/bc/H.1 @@ -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: diff --git a/manuals/bc/H.1.md b/manuals/bc/H.1.md index 99c88db93230..47b17f1188e4 100644 --- a/manuals/bc/H.1.md +++ b/manuals/bc/H.1.md @@ -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: diff --git a/manuals/bc/HN.1 b/manuals/bc/HN.1 index 4773ff77efea..0687cb263b6e 100644 --- a/manuals/bc/HN.1 +++ b/manuals/bc/HN.1 @@ -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: diff --git a/manuals/bc/HN.1.md b/manuals/bc/HN.1.md index d5b3324514ad..12ed1c9c5e74 100644 --- a/manuals/bc/HN.1.md +++ b/manuals/bc/HN.1.md @@ -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: diff --git a/manuals/bc/N.1 b/manuals/bc/N.1 index 56fca3d02b4d..40dbad9bb2f2 100644 --- a/manuals/bc/N.1 +++ b/manuals/bc/N.1 @@ -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: diff --git a/manuals/bc/N.1.md b/manuals/bc/N.1.md index 51dad376b56d..92c239c0b12b 100644 --- a/manuals/bc/N.1.md +++ b/manuals/bc/N.1.md @@ -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: diff --git a/manuals/build.md b/manuals/build.md index 1ed2b269f13c..aa0ed78e2d72 100644 --- a/manuals/build.md +++ b/manuals/build.md @@ -83,6 +83,23 @@ where `` 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 diff --git a/manuals/dc/A.1 b/manuals/dc/A.1 index a7ff2e3a6963..3dff3b16d080 100644 --- a/manuals/dc/A.1 +++ b/manuals/dc/A.1 @@ -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: diff --git a/manuals/dc/A.1.md b/manuals/dc/A.1.md index 0007cc76760a..618543d7f397 100644 --- a/manuals/dc/A.1.md +++ b/manuals/dc/A.1.md @@ -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: diff --git a/manuals/dc/E.1 b/manuals/dc/E.1 index 8760477a03ff..a677bcea0c0c 100644 --- a/manuals/dc/E.1 +++ b/manuals/dc/E.1 @@ -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: diff --git a/manuals/dc/E.1.md b/manuals/dc/E.1.md index 6a2c465e5642..a138fdb32158 100644 --- a/manuals/dc/E.1.md +++ b/manuals/dc/E.1.md @@ -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: diff --git a/manuals/dc/EH.1 b/manuals/dc/EH.1 index 4506001dfe55..97c05ca44094 100644 --- a/manuals/dc/EH.1 +++ b/manuals/dc/EH.1 @@ -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: diff --git a/manuals/dc/EH.1.md b/manuals/dc/EH.1.md index 06ec59d4b3f7..459f8ac12e7e 100644 --- a/manuals/dc/EH.1.md +++ b/manuals/dc/EH.1.md @@ -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: diff --git a/manuals/dc/EHN.1 b/manuals/dc/EHN.1 index 1124d907bdd9..223bd9f08dfa 100644 --- a/manuals/dc/EHN.1 +++ b/manuals/dc/EHN.1 @@ -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: diff --git a/manuals/dc/EHN.1.md b/manuals/dc/EHN.1.md index 50cb37ef2586..56ac39ed599e 100644 --- a/manuals/dc/EHN.1.md +++ b/manuals/dc/EHN.1.md @@ -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: diff --git a/manuals/dc/EN.1 b/manuals/dc/EN.1 index beae0e46a9b6..8c2d14f57840 100644 --- a/manuals/dc/EN.1 +++ b/manuals/dc/EN.1 @@ -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: diff --git a/manuals/dc/EN.1.md b/manuals/dc/EN.1.md index db6f27f34576..03836923c00e 100644 --- a/manuals/dc/EN.1.md +++ b/manuals/dc/EN.1.md @@ -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: diff --git a/manuals/dc/H.1 b/manuals/dc/H.1 index b4ab9f511080..f27358fb7f12 100644 --- a/manuals/dc/H.1 +++ b/manuals/dc/H.1 @@ -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: diff --git a/manuals/dc/H.1.md b/manuals/dc/H.1.md index 647d486adc38..c97cc8b58eef 100644 --- a/manuals/dc/H.1.md +++ b/manuals/dc/H.1.md @@ -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: diff --git a/manuals/dc/HN.1 b/manuals/dc/HN.1 index eb35cb23ff7b..13a39ef26540 100644 --- a/manuals/dc/HN.1 +++ b/manuals/dc/HN.1 @@ -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: diff --git a/manuals/dc/HN.1.md b/manuals/dc/HN.1.md index 70c962624833..47c2a0330ae9 100644 --- a/manuals/dc/HN.1.md +++ b/manuals/dc/HN.1.md @@ -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: diff --git a/manuals/dc/N.1 b/manuals/dc/N.1 index c5cc36ac9b10..16f89b7ee2a1 100644 --- a/manuals/dc/N.1 +++ b/manuals/dc/N.1 @@ -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: diff --git a/manuals/dc/N.1.md b/manuals/dc/N.1.md index fea23028e483..a14c922b4dbc 100644 --- a/manuals/dc/N.1.md +++ b/manuals/dc/N.1.md @@ -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: diff --git a/scripts/exec-install.sh b/scripts/exec-install.sh index 25d56c6fc688..f36caa37e6f8 100755 --- a/scripts/exec-install.sh +++ b/scripts/exec-install.sh @@ -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. diff --git a/scripts/karatsuba.py b/scripts/karatsuba.py index b8505186b526..9aa1c2a5457f 100755 --- a/scripts/karatsuba.py +++ b/scripts/karatsuba.py @@ -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)) diff --git a/src/args.c b/src/args.c index 6601cfb2eeb6..5eee96f5b559 100644 --- a/src/args.c +++ b/src/args.c @@ -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; diff --git a/src/bc_lex.c b/src/bc_lex.c index cdbdf24b17ac..bd03d169ee06 100644 --- a/src/bc_lex.c +++ b/src/bc_lex.c @@ -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) { diff --git a/src/bc_parse.c b/src/bc_parse.c index c2fc2186a065..91de31ad5389 100644 --- a/src/bc_parse.c +++ b/src/bc_parse.c @@ -329,12 +329,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 +355,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 +425,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; } /** @@ -1315,15 +1309,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); @@ -1759,7 +1747,7 @@ 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 +1768,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; } /** diff --git a/src/dc_lex.c b/src/dc_lex.c index 5c6950ba9698..576d50943f25 100644 --- a/src/dc_lex.c +++ b/src/dc_lex.c @@ -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) { diff --git a/src/dc_parse.c b/src/dc_parse.c index b9b5afb66c44..26aad6796d88 100644 --- a/src/dc_parse.c +++ b/src/dc_parse.c @@ -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 diff --git a/src/file.c b/src/file.c index 35a4647dfabf..627664a9c261 100644 --- a/src/file.c +++ b/src/file.c @@ -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) { diff --git a/src/history.c b/src/history.c index b5ba0758075c..9f158413efc2 100644 --- a/src/history.c +++ b/src/history.c @@ -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"); diff --git a/src/lex.c b/src/lex.c index f8b32451aef7..51e9f31bfa11 100644 --- a/src/lex.c +++ b/src/lex.c @@ -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); } diff --git a/src/library.c b/src/library.c index e0bd3ee98b85..a9246a025206 100644 --- a/src/library.c +++ b/src/library.c @@ -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); diff --git a/src/opt.c b/src/opt.c index ddc78362e7b1..971e7e5f3ca5 100644 --- a/src/opt.c +++ b/src/opt.c @@ -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; } diff --git a/src/parse.c b/src/parse.c index ea4c25e8ba10..7fdfa31df4ac 100644 --- a/src/parse.c +++ b/src/parse.c @@ -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) { diff --git a/src/program.c b/src/program.c index 1ff9c24f323b..bc5b88011638 100644 --- a/src/program.c +++ b/src/program.c @@ -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); } diff --git a/src/rand.c b/src/rand.c index bfc79be7cfb9..a3b8942a6042 100644 --- a/src/rand.c +++ b/src/rand.c @@ -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) { diff --git a/src/read.c b/src/read.c index 84621ad3acac..b9cd4db7bb49 100644 --- a/src/read.c +++ b/src/read.c @@ -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. diff --git a/src/vm.c b/src/vm.c index 853dff0820dd..ef2257644f52 100644 --- a/src/vm.c +++ b/src/vm.c @@ -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)) { diff --git a/tests/bc/timeconst.sh b/tests/bc/timeconst.sh index 45e10c77bdf4..8b6e1ec596fc 100755 --- a/tests/bc/timeconst.sh +++ b/tests/bc/timeconst.sh @@ -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" diff --git a/tests/history.py b/tests/history.py index 17006c93ef2d..84e32f9612c4 100755 --- a/tests/history.py +++ b/tests/history.py @@ -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, diff --git a/tests/history.sh b/tests/history.sh index 92db985a4f86..1898ae5499dc 100755 --- a/tests/history.sh +++ b/tests/history.sh @@ -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="$?" diff --git a/vs/bc.vcxproj b/vs/bc.vcxproj index 19b53d66a405..6cfd7d489927 100644 --- a/vs/bc.vcxproj +++ b/vs/bc.vcxproj @@ -102,7 +102,7 @@ Level3 true - 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) + 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) ..\include MultiThreadedDebug true @@ -123,7 +123,7 @@ true true true - 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) + 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) ..\include MultiThreaded true @@ -144,7 +144,7 @@ Level3 true - 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) + 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) ..\include MultiThreadedDebug true @@ -164,7 +164,7 @@ Level3 true true - 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) + 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) ..\include MultiThreaded true From e63540eed295749528548c2e3a90f5a6e57275c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20E=C3=9Fer?= Date: Tue, 30 Nov 2021 18:33:40 +0100 Subject: [PATCH 2/2] vendor/bc: import release 5.2.1 This release 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. --- NEWS.md | 6 ++++++ configure.sh | 4 +++- include/status.h | 4 ++++ include/version.h | 2 +- locales/de_DE.ISO8859-1.msg | 10 ++++++---- locales/de_DE.UTF-8.msg | 10 ++++++---- locales/en_US.msg | 10 ++++++---- locales/es_ES.ISO8859-1.msg | 10 ++++++---- locales/es_ES.UTF-8.msg | 10 ++++++---- locales/fr_FR.ISO8859-1.msg | 10 ++++++---- locales/fr_FR.UTF-8.msg | 10 ++++++---- locales/ja_JP.UTF-8.msg | 10 ++++++---- locales/ja_JP.eucJP.msg | 10 ++++++---- locales/nl_NL.ISO8859-1.msg | 10 ++++++---- locales/nl_NL.UTF-8.msg | 10 ++++++---- locales/pl_PL.ISO8859-2.msg | 10 ++++++---- locales/pl_PL.UTF-8.msg | 10 ++++++---- locales/pt_PT.ISO8859-1.msg | 10 ++++++---- locales/pt_PT.UTF-8.msg | 10 ++++++---- locales/ru_RU.CP1251.msg | 10 ++++++---- locales/ru_RU.CP866.msg | 10 ++++++---- locales/ru_RU.ISO8859-5.msg | 10 ++++++---- locales/ru_RU.KOI8-R.msg | 10 ++++++---- locales/ru_RU.UTF-8.msg | 10 ++++++---- locales/zh_CN.GB18030.msg | 10 ++++++---- locales/zh_CN.GB2312.msg | 10 ++++++---- locales/zh_CN.GBK.msg | 10 ++++++---- locales/zh_CN.UTF-8.msg | 10 ++++++---- locales/zh_CN.eucCN.msg | 10 ++++++---- src/bc_parse.c | 28 +++++++++++++++++++++++++++- src/data.c | 3 ++- tests/bc/all.txt | 1 + tests/bc/misc8.txt | 8 ++++++++ tests/bc/misc8_results.txt | 3 +++ tests/bc/posix_errors.txt | 1 + 35 files changed, 206 insertions(+), 104 deletions(-) create mode 100644 tests/bc/misc8.txt create mode 100644 tests/bc/misc8_results.txt diff --git a/NEWS.md b/NEWS.md index fa2df6749783..5d0126b821a8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,11 @@ # 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 diff --git a/configure.sh b/configure.sh index 8a6a7817fd2a..76ffb2b9a18e 100755 --- a/configure.sh +++ b/configure.sh @@ -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' diff --git a/include/status.h b/include/status.h index 3a23b09dc873..993b5e698fb3 100644 --- a/include/status.h +++ b/include/status.h @@ -480,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, diff --git a/include/version.h b/include/version.h index 296dbc79b547..eca73baf508f 100644 --- a/include/version.h +++ b/include/version.h @@ -37,6 +37,6 @@ #define BC_VERSION_H /// The current version. -#define VERSION 5.2.0 +#define VERSION 5.2.1 #endif // BC_VERSION_H diff --git a/locales/de_DE.ISO8859-1.msg b/locales/de_DE.ISO8859-1.msg index 76f2ac4190f6..dc7545e3ed72 100644 --- a/locales/de_DE.ISO8859-1.msg +++ b/locales/de_DE.ISO8859-1.msg @@ -77,10 +77,12 @@ $set 4 22 "POSIX erlaubt keine Vergleichsoperatoren au遝rhalb von if-Anweisungen oder Schleifen" 23 "POSIX ben鰐igt 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黮tigen 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 diff --git a/locales/de_DE.UTF-8.msg b/locales/de_DE.UTF-8.msg index c4dad4cd3a60..7956615e849f 100644 --- a/locales/de_DE.UTF-8.msg +++ b/locales/de_DE.UTF-8.msg @@ -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 diff --git a/locales/en_US.msg b/locales/en_US.msg index 707950a5767d..adc1cc4537b9 100644 --- a/locales/en_US.msg +++ b/locales/en_US.msg @@ -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 diff --git a/locales/es_ES.ISO8859-1.msg b/locales/es_ES.ISO8859-1.msg index 8d74f884f811..30c965111de6 100644 --- a/locales/es_ES.ISO8859-1.msg +++ b/locales/es_ES.ISO8859-1.msg @@ -77,10 +77,12 @@ $set 4 22 "POSIX no permite operadores de comparaci髇 aparte de \"if\" expresi髇 o bucles" 23 "POSIX requiere 0 o 1 operadores de comparis髇 para cada condici髇" 24 "POSIX requiere todos 3 partes de una bucla que no esta vac韔" -25 "POSIX no permite una notaci髇 exponencial" -26 "POSIX no permite una referencia a una matriz como un par醡etro de funci髇" -27 "POSIX requiere el llave de la izquierda que sea en la misma l韓ea que los par醡etros de la funci髇" -28 "POSIX no permite asignar cadenas a variables o matrices" +25 "POSIX requiere una nueva l韓ea entre un punto y coma y una definici髇 de funci髇" +26 "POSIX no permite una notaci髇 exponencial" +27 "POSIX no permite una referencia a una matriz como un par醡etro de funci髇" +28 "POSIX no permite funciones void" +29 "POSIX requiere el llave de la izquierda que sea en la misma l韓ea que los par醡etros de la funci髇" +30 "POSIX no permite asignar cadenas a variables o matrices" $ Runtime errors. $set 5 diff --git a/locales/es_ES.UTF-8.msg b/locales/es_ES.UTF-8.msg index 26559e6e9b88..1721dd3d8f2a 100644 --- a/locales/es_ES.UTF-8.msg +++ b/locales/es_ES.UTF-8.msg @@ -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 diff --git a/locales/fr_FR.ISO8859-1.msg b/locales/fr_FR.ISO8859-1.msg index 8e894e043bbc..5d772abcc4ef 100644 --- a/locales/fr_FR.ISO8859-1.msg +++ b/locales/fr_FR.ISO8859-1.msg @@ -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 diff --git a/locales/fr_FR.UTF-8.msg b/locales/fr_FR.UTF-8.msg index 8e894e043bbc..6393ab0e5f70 100644 --- a/locales/fr_FR.UTF-8.msg +++ b/locales/fr_FR.UTF-8.msg @@ -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 diff --git a/locales/ja_JP.UTF-8.msg b/locales/ja_JP.UTF-8.msg index 4477f2bc548b..3c51aca8194f 100644 --- a/locales/ja_JP.UTF-8.msg +++ b/locales/ja_JP.UTF-8.msg @@ -77,10 +77,12 @@ $set 4 22 "POSIX 銇 if 鏂囥倓銉兗銉椼伄澶栥伄姣旇純婕旂畻瀛愩倰瑷卞彲銇椼伨銇涖倱銆" 23 "POSIX銇潯浠躲仈銇ㄣ伀0銇俱仧銇1銇瘮杓冩紨绠楀瓙銈掑繀瑕併仺銇椼伨銇欍" 24 "POSIX銇痜or銉兗銉椼伄3銇ゃ伄閮ㄥ垎銇屻仚銇广仸绌恒仹銇亜銇撱仺銈掕姹傘仐銇俱仚銆" -25 "POSIX銇寚鏁拌〃瑷樸倰瑷卞彲銇椼伨銇涖倱銆" -26 "POSIX 銇枹鏁般儜銉┿儭銉笺偪銇ㄣ仐銇﹂厤鍒楀弬鐓с倰瑷卞彲銇椼伨銇涖倱銆" -27 "POSIX銇с伅銆侀枹鏁般儤銉冦儉銇ㄥ悓銇樿銇乏涓嫭寮с亴銇傘倠銇撱仺銇屽繀瑕併仹銇欍" -28 "POSIX銇с伅銆佸鏁般倓閰嶅垪銇枃瀛楀垪銈掑壊銈婂綋銇︺倠銇撱仺銇仹銇嶃伨銇涖倱銆" +25 "POSIX銇с伅銆併偦銉熴偝銉兂銇ㄩ枹鏁板畾缇┿伄闁撱伀鏀硅銈掑叆銈屻倠蹇呰銇屻亗銈娿伨銇欍" +26 "POSIX銇寚鏁拌〃瑷樸倰瑷卞彲銇椼伨銇涖倱銆" +27 "POSIX 銇枹鏁般儜銉┿儭銉笺偪銇ㄣ仐銇﹂厤鍒楀弬鐓с倰瑷卞彲銇椼伨銇涖倱銆" +28 "POSIX銇с伅void闁㈡暟銈掕獚銈併仸銇勩伨銇涖倱銆" +29 "POSIX銇с伅銆侀枹鏁般儤銉冦儉銇ㄥ悓銇樿銇乏涓嫭寮с亴銇傘倠銇撱仺銇屽繀瑕併仹銇欍" +30 "POSIX銇с伅銆佸鏁般倓閰嶅垪銇枃瀛楀垪銈掑壊銈婂綋銇︺倠銇撱仺銇仹銇嶃伨銇涖倱銆" $ 銉┿兂銈裤偆銉犮偍銉┿兗銆 $set 5 diff --git a/locales/ja_JP.eucJP.msg b/locales/ja_JP.eucJP.msg index a907cd7cf0e3..74bd09c27fd5 100644 --- a/locales/ja_JP.eucJP.msg +++ b/locales/ja_JP.eucJP.msg @@ -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 diff --git a/locales/nl_NL.ISO8859-1.msg b/locales/nl_NL.ISO8859-1.msg index 76b8577108e8..2f60de23cca1 100644 --- a/locales/nl_NL.ISO8859-1.msg +++ b/locales/nl_NL.ISO8859-1.msg @@ -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雔e 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雔e 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 diff --git a/locales/nl_NL.UTF-8.msg b/locales/nl_NL.UTF-8.msg index 51acb9867e22..599628a6cc51 100644 --- a/locales/nl_NL.UTF-8.msg +++ b/locales/nl_NL.UTF-8.msg @@ -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 diff --git a/locales/pl_PL.ISO8859-2.msg b/locales/pl_PL.ISO8859-2.msg index d1d77d7e0b57..a36d5fe8beb5 100644 --- a/locales/pl_PL.ISO8859-2.msg +++ b/locales/pl_PL.ISO8859-2.msg @@ -77,10 +77,12 @@ $set 4 22 "POSIX nie pozwala na por體nywanie operator體 na zewn眛rz, je秎i deklaracje lub p阾le" 23 "POSIX wymaga 0 lub 1 operatora por體nawczego na jeden warunek" 24 "POSIX wymaga, aby wszystkie 3 cz甓ci p阾li nie by硑 puste" -25 "POSIX nie pozwala na notacj wyk砤dnicz" -26 "POSIX nie zezwala na odniesienia do tablicy jako parametr體 funkcji" -27 "POSIX wymaga, aby lewe usztywnienie znajdowa硂 si na tej samej linii co nag丑wek funkcji" -28 "POSIX nie pozwala na przypisywanie ci眊體 znak體 do zmiennych lub tablic" +25 "POSIX wymaga nowej linii pomi阣zy 秗ednikiem a definicj funkcji" +26 "POSIX nie pozwala na notacj wyk砤dnicz" +27 "POSIX nie zezwala na odniesienia do tablicy jako parametr體 funkcji" +28 "POSIX nie dopuszcza funkcji void" +29 "POSIX wymaga, aby lewe usztywnienie znajdowa硂 si na tej samej linii co nag丑wek funkcji" +30 "POSIX nie pozwala na przypisywanie ci眊體 znak體 do zmiennych lub tablic" $ B酬dy Runtime'u. $set 5 diff --git a/locales/pl_PL.UTF-8.msg b/locales/pl_PL.UTF-8.msg index a23a98edd1d2..ee297161a895 100644 --- a/locales/pl_PL.UTF-8.msg +++ b/locales/pl_PL.UTF-8.msg @@ -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 diff --git a/locales/pt_PT.ISO8859-1.msg b/locales/pt_PT.ISO8859-1.msg index 7a17f0642cc9..6197a73d0fe2 100644 --- a/locales/pt_PT.ISO8859-1.msg +++ b/locales/pt_PT.ISO8859-1.msg @@ -77,10 +77,12 @@ $set 4 22 "POSIX n鉶 permite operadores de compara玢o fora das express鮡s 'if' ou loops" 23 "POSIX requer operadores 0 ou 1 de compara玢o por condi玢o" 24 "POSIX n鉶 permite uma express鉶 vazia em um loop 'for'" -25 "POSIX n鉶 permite nota玢o exponencial" -26 "POSIX n鉶 permite refer阯cias de matriz como par鈓etros de fun玢o" -27 "POSIX requer que o cabe鏰lho da fun玢o '{' estejam na mesma linha" -28 "POSIX n鉶 permite a atribui玢o de cadeias de caracteres a vari醰eis ou matrizes" +25 "POSIX requer uma nova linha entre um ponto-e-v韗gula e uma defini玢o de fun玢o" +26 "POSIX n鉶 permite nota玢o exponencial" +27 "POSIX n鉶 permite refer阯cias de matriz como par鈓etros de fun玢o" +28 "POSIX n鉶 permite fun珲es nulas" +29 "POSIX requer que o cabe鏰lho da fun玢o '{' estejam na mesma linha" +30 "POSIX n鉶 permite a atribui玢o de cadeias de caracteres a vari醰eis ou matrizes" $ Runtime errors. $set 5 diff --git a/locales/pt_PT.UTF-8.msg b/locales/pt_PT.UTF-8.msg index 2f6a4683a376..768f8807ebfc 100644 --- a/locales/pt_PT.UTF-8.msg +++ b/locales/pt_PT.UTF-8.msg @@ -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 diff --git a/locales/ru_RU.CP1251.msg b/locales/ru_RU.CP1251.msg index 6b1d93aa2110..a094e08e4afb 100644 --- a/locales/ru_RU.CP1251.msg +++ b/locales/ru_RU.CP1251.msg @@ -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 diff --git a/locales/ru_RU.CP866.msg b/locales/ru_RU.CP866.msg index b693428b9a3c..79070cda2e0c 100644 --- a/locales/ru_RU.CP866.msg +++ b/locales/ru_RU.CP866.msg @@ -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 diff --git a/locales/ru_RU.ISO8859-5.msg b/locales/ru_RU.ISO8859-5.msg index 35af400c5831..4c544e94f846 100644 --- a/locales/ru_RU.ISO8859-5.msg +++ b/locales/ru_RU.ISO8859-5.msg @@ -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 diff --git a/locales/ru_RU.KOI8-R.msg b/locales/ru_RU.KOI8-R.msg index 98c667095852..50c716b5ca2e 100644 --- a/locales/ru_RU.KOI8-R.msg +++ b/locales/ru_RU.KOI8-R.msg @@ -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 diff --git a/locales/ru_RU.UTF-8.msg b/locales/ru_RU.UTF-8.msg index f7c1dc58c4db..e37bb2182caf 100644 --- a/locales/ru_RU.UTF-8.msg +++ b/locales/ru_RU.UTF-8.msg @@ -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 diff --git a/locales/zh_CN.GB18030.msg b/locales/zh_CN.GB18030.msg index fb80db7de55d..a2210b19ed29 100644 --- a/locales/zh_CN.GB18030.msg +++ b/locales/zh_CN.GB18030.msg @@ -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 diff --git a/locales/zh_CN.GB2312.msg b/locales/zh_CN.GB2312.msg index fb80db7de55d..a2210b19ed29 100644 --- a/locales/zh_CN.GB2312.msg +++ b/locales/zh_CN.GB2312.msg @@ -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 diff --git a/locales/zh_CN.GBK.msg b/locales/zh_CN.GBK.msg index fb80db7de55d..a2210b19ed29 100644 --- a/locales/zh_CN.GBK.msg +++ b/locales/zh_CN.GBK.msg @@ -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 diff --git a/locales/zh_CN.UTF-8.msg b/locales/zh_CN.UTF-8.msg index c327c0b1b98c..92d1bb767cb0 100644 --- a/locales/zh_CN.UTF-8.msg +++ b/locales/zh_CN.UTF-8.msg @@ -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 diff --git a/locales/zh_CN.eucCN.msg b/locales/zh_CN.eucCN.msg index fb80db7de55d..a2210b19ed29 100644 --- a/locales/zh_CN.eucCN.msg +++ b/locales/zh_CN.eucCN.msg @@ -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 diff --git a/src/bc_parse.c b/src/bc_parse.c index 91de31ad5389..8849c1b8e9c7 100644 --- a/src/bc_parse.c +++ b/src/bc_parse.c @@ -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). @@ -881,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); } @@ -1741,6 +1759,14 @@ 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) { diff --git a/src/data.c b/src/data.c index 82475299ed78..959af600c1af 100644 --- a/src/data.c +++ b/src/data.c @@ -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 diff --git a/tests/bc/all.txt b/tests/bc/all.txt index 23244773b933..f85491d12424 100644 --- a/tests/bc/all.txt +++ b/tests/bc/all.txt @@ -43,6 +43,7 @@ misc4 misc5 misc6 misc7 +misc8 void rand recursive_arrays diff --git a/tests/bc/misc8.txt b/tests/bc/misc8.txt new file mode 100644 index 000000000000..8bef63316ef8 --- /dev/null +++ b/tests/bc/misc8.txt @@ -0,0 +1,8 @@ +define a(){ + return 5 +}define b(){ + return 6 +} +24 +a() +b() diff --git a/tests/bc/misc8_results.txt b/tests/bc/misc8_results.txt new file mode 100644 index 000000000000..daee0f1b2fbf --- /dev/null +++ b/tests/bc/misc8_results.txt @@ -0,0 +1,3 @@ +24 +5 +6 diff --git a/tests/bc/posix_errors.txt b/tests/bc/posix_errors.txt index d880600f7bb1..584a0198b5b3 100644 --- a/tests/bc/posix_errors.txt +++ b/tests/bc/posix_errors.txt @@ -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; }