Import new 2-clause BSD licenced implementation of the bc and dc commands
These implementations of the bc and dc programs offer a number of advantages compared to the current implementations in the FreeBSD base system: - They do not depend on external large number functions (i.e. no dependency on OpenSSL or any other large number library) - They implements all features found in GNU bc/dc (with the exception of the forking of sub-processes, which the author of this version considers as a security issue). - They are significantly faster than the current code in base (more than 2 orders of magnitude in some of my tests, e.g. for 12345^100000). - They should be fully compatible with all features and the behavior of the current implementations in FreeBSD (not formally verified). - They support POSIX message catalogs and come with localized messages in Chinese, Dutch, English, French, German, Japanese, Polish, Portugueze, and Russian. - They offer very detailed man-pages that provide far more information than the current ones. Approved by: imp Obtained from: https://git.yzena.com/gavin/bc Differential Revision: https://reviews.freebsd.org/D19982
This commit is contained in:
commit
1f958cfad7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/bc/dist/; revision=362697 svn path=/vendor/bc/3.0.2/; revision=362698; tag=vendor/bc/3.0.2
54
.gitignore
vendored
Normal file
54
.gitignore
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
*.config
|
||||
*.creator
|
||||
*.files
|
||||
*.includes
|
||||
*.creator.user*
|
||||
*.cflags
|
||||
*.cxxflags
|
||||
bin/*bc
|
||||
bin/*bc.exe
|
||||
bin/*dc
|
||||
bin/*dc.exe
|
||||
bc.old
|
||||
*.o
|
||||
*.a
|
||||
.log_*.txt
|
||||
.test.txt
|
||||
.math.txt
|
||||
.results.txt
|
||||
.ops.txt
|
||||
gen/strgen
|
||||
lib.c
|
||||
lib2.c
|
||||
lib3.c
|
||||
bc_help.c
|
||||
dc_help.c
|
||||
config.mak
|
||||
timeconst.bc
|
||||
Makefile
|
||||
|
||||
.gdb_history
|
||||
|
||||
# Ignore the generated test files
|
||||
parse.txt
|
||||
parse_results.txt
|
||||
print.txt
|
||||
print_results.txt
|
||||
bessel.txt
|
||||
bessel_results.txt
|
||||
prime.txt
|
||||
stream.txt
|
||||
tests/bc/scripts/add.txt
|
||||
tests/bc/scripts/divide.txt
|
||||
tests/bc/scripts/multiply.txt
|
||||
tests/bc/scripts/subtract.txt
|
||||
perf.data
|
||||
perf.data.old
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.gcov
|
||||
*.html
|
||||
*.profraw
|
||||
|
||||
cscope*.out
|
||||
tags
|
42
.travis.yml
Normal file
42
.travis.yml
Normal file
@ -0,0 +1,42 @@
|
||||
dist: bionic
|
||||
|
||||
language: c
|
||||
|
||||
arch:
|
||||
- amd64
|
||||
- arm64
|
||||
- ppc64le
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
env:
|
||||
global:
|
||||
- CODECOV_TOKEN="040ce7eb-5bc7-4040-8324-364f3ef4baa3"
|
||||
- CFLAGS="-coverage -DBC_RAND_BUILTIN=0"
|
||||
matrix:
|
||||
- CONFIGURE_ARGS=-fHNPOg GEN_HOST=1 LONG_BIT=64
|
||||
- CONFIGURE_ARGS=-bfHNPOg GEN_HOST=1 LONG_BIT=64
|
||||
- CONFIGURE_ARGS=-dfHNPOg GEN_HOST=1 LONG_BIT=64
|
||||
- CONFIGURE_ARGS=-fEHNPOg GEN_HOST=1 LONG_BIT=64
|
||||
- CONFIGURE_ARGS=-bfEHNPOg GEN_HOST=1 LONG_BIT=64
|
||||
- CONFIGURE_ARGS=-dfEHNPOg GEN_HOST=1 LONG_BIT=64
|
||||
- CONFIGURE_ARGS=-fHNPOg GEN_HOST=1 LONG_BIT=32
|
||||
- CONFIGURE_ARGS=-bfHNPOg GEN_HOST=1 LONG_BIT=32
|
||||
- CONFIGURE_ARGS=-dfHNPOg GEN_HOST=1 LONG_BIT=32
|
||||
- CONFIGURE_ARGS=-fEHNPOg GEN_HOST=1 LONG_BIT=32
|
||||
- CONFIGURE_ARGS=-bfEHNPOg GEN_HOST=1 LONG_BIT=32
|
||||
- CONFIGURE_ARGS=-dfEHNPOg GEN_HOST=1 LONG_BIT=32
|
||||
|
||||
before_install:
|
||||
- sudo apt-get install -y dc
|
||||
- pip install --user codecov
|
||||
|
||||
before_script:
|
||||
- curl -o tests/bc/scripts/timeconst.bc https://raw.githubusercontent.com/torvalds/linux/master/kernel/time/timeconst.bc
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
script:
|
||||
- if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./configure.sh "$CONFIGURE_ARGS" && make -j4 && make -j4 test ; fi
|
59
LICENSE.md
Normal file
59
LICENSE.md
Normal file
@ -0,0 +1,59 @@
|
||||
# License
|
||||
|
||||
Copyright (c) 2018-2020 Gavin D. Howard <yzena.tech@gmail.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
## History
|
||||
|
||||
The files `src/history.c` and `include/history.h` are under the following
|
||||
copyrights and license:
|
||||
|
||||
Copyright (c) 2010-2014, Salvatore Sanfilippo <antirez at gmail dot com><br>
|
||||
Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com><br>
|
||||
Copyright (c) 2018 rain-1 <rain1@openmailbox.org><br>
|
||||
Copyright (c) 2018-2020, Gavin D. Howard <yzena.tech@gmail.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
362
Makefile.in
Normal file
362
Makefile.in
Normal file
@ -0,0 +1,362 @@
|
||||
#
|
||||
# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# %%WARNING%%
|
||||
#
|
||||
.POSIX:
|
||||
|
||||
VERSION = 3.0.2
|
||||
|
||||
SRC = %%SRC%%
|
||||
OBJ = %%OBJ%%
|
||||
GCDA = %%GCDA%%
|
||||
GCNO = %%GCNO%%
|
||||
|
||||
BC_SRC = %%BC_SRC%%
|
||||
BC_OBJ = %%BC_OBJ%%
|
||||
BC_GCDA = %%BC_GCDA%%
|
||||
BC_GCNO = %%BC_GCNO%%
|
||||
|
||||
DC_SRC = %%DC_SRC%%
|
||||
DC_OBJ = %%DC_OBJ%%
|
||||
DC_GCDA = %%DC_GCDA%%
|
||||
DC_GCNO = %%DC_GCNO%%
|
||||
|
||||
HISTORY_SRC = %%HISTORY_SRC%%
|
||||
HISTORY_OBJ = %%HISTORY_OBJ%%
|
||||
HISTORY_GCDA = %%HISTORY_GCDA%%
|
||||
HISTORY_GCNO = %%HISTORY_GCNO%%
|
||||
|
||||
RAND_SRC = %%RAND_SRC%%
|
||||
RAND_OBJ = %%RAND_OBJ%%
|
||||
RAND_GCDA = %%RAND_GCDA%%
|
||||
RAND_GCNO = %%RAND_GCNO%%
|
||||
|
||||
BC_ENABLED_NAME = BC_ENABLED
|
||||
BC_ENABLED = %%BC_ENABLED%%
|
||||
DC_ENABLED_NAME = DC_ENABLED
|
||||
DC_ENABLED = %%DC_ENABLED%%
|
||||
|
||||
GEN_DIR = gen
|
||||
GEN = %%GEN%%
|
||||
GEN_EXEC = $(GEN_DIR)/$(GEN)
|
||||
GEN_C = $(GEN_DIR)/$(GEN).c
|
||||
|
||||
GEN_EMU = %%GEN_EMU%%
|
||||
|
||||
BC_LIB = $(GEN_DIR)/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_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_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_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%%
|
||||
|
||||
BC = bc
|
||||
DC = dc
|
||||
BC_EXEC = $(BIN)/$(EXEC_PREFIX)$(BC)
|
||||
DC_EXEC = $(BIN)/$(EXEC_PREFIX)$(DC)
|
||||
|
||||
MANUALS = manuals
|
||||
BC_MANPAGE_NAME = $(EXEC_PREFIX)$(BC)$(EXEC_SUFFIX).1
|
||||
BC_MANPAGE = $(MANUALS)/$(BC).1
|
||||
BC_RONN = $(BC_MANPAGE).ronn
|
||||
DC_MANPAGE_NAME = $(EXEC_PREFIX)$(DC)$(EXEC_SUFFIX).1
|
||||
DC_MANPAGE = $(MANUALS)/$(DC).1
|
||||
DC_RONN = $(DC_MANPAGE).ronn
|
||||
|
||||
MANPAGE_INSTALL_ARGS = -Dm644
|
||||
|
||||
%%DESTDIR%%
|
||||
BINDIR = %%BINDIR%%
|
||||
MAN1DIR = %%MAN1DIR%%
|
||||
MAIN_EXEC = $(EXEC_PREFIX)$(%%MAIN_EXEC%%)$(EXEC_SUFFIX)
|
||||
EXEC = $(%%EXEC%%)
|
||||
NLSPATH = %%NLSPATH%%
|
||||
|
||||
BC_ENABLE_HISTORY = %%HISTORY%%
|
||||
BC_ENABLE_EXTRA_MATH_NAME = BC_ENABLE_EXTRA_MATH
|
||||
BC_ENABLE_EXTRA_MATH = %%EXTRA_MATH%%
|
||||
BC_ENABLE_NLS = %%NLS%%
|
||||
BC_ENABLE_PROMPT = %%PROMPT%%
|
||||
BC_LONG_BIT = %%LONG_BIT%%
|
||||
|
||||
RM = rm
|
||||
MKDIR = mkdir
|
||||
|
||||
INSTALL = ./install.sh
|
||||
SAFE_INSTALL = ./safe-install.sh
|
||||
LINK = ./link.sh
|
||||
MANPAGE = ./manpage.sh
|
||||
KARATSUBA = ./karatsuba.py
|
||||
LOCALE_INSTALL = ./locale_install.sh
|
||||
LOCALE_UNINSTALL = ./locale_uninstall.sh
|
||||
|
||||
VALGRIND_ARGS = --error-exitcode=100 --leak-check=full --show-leak-kinds=all --errors-for-leak-kinds=all
|
||||
|
||||
BC_NUM_KARATSUBA_LEN = %%KARATSUBA_LEN%%
|
||||
|
||||
CPPFLAGS1 = -D$(BC_ENABLED_NAME)=$(BC_ENABLED) -D$(DC_ENABLED_NAME)=$(DC_ENABLED)
|
||||
CPPFLAGS2 = $(CPPFLAGS1) -I./include/ -DVERSION=$(VERSION) %%LONG_BIT_DEFINE%%
|
||||
CPPFLAGS3 = $(CPPFLAGS2) -DEXECPREFIX=$(EXEC_PREFIX) -DMAINEXEC=$(MAIN_EXEC)
|
||||
CPPFLAGS4 = $(CPPFLAGS3) -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700
|
||||
CPPFLAGS5 = $(CPPFLAGS4) -DBC_NUM_KARATSUBA_LEN=$(BC_NUM_KARATSUBA_LEN)
|
||||
CPPFLAGS6 = $(CPPFLAGS5) -DBC_ENABLE_NLS=$(BC_ENABLE_NLS) -DBC_ENABLE_PROMPT=$(BC_ENABLE_PROMPT)
|
||||
CPPFLAGS7 = $(CPPFLAGS6) -D$(BC_ENABLE_EXTRA_MATH_NAME)=$(BC_ENABLE_EXTRA_MATH)
|
||||
CPPFLAGS = $(CPPFLAGS7) -DBC_ENABLE_HISTORY=$(BC_ENABLE_HISTORY)
|
||||
CFLAGS = $(CPPFLAGS) %%CPPFLAGS%% %%CFLAGS%%
|
||||
LDFLAGS = %%LDFLAGS%%
|
||||
|
||||
HOSTCFLAGS = %%HOSTCFLAGS%%
|
||||
|
||||
CC = %%CC%%
|
||||
HOSTCC = %%HOSTCC%%
|
||||
|
||||
BC_LIB_C_ARGS = bc_lib bc.h bc_lib_name $(BC_ENABLED_NAME) 1
|
||||
BC_LIB2_C_ARGS = bc_lib2 bc.h bc_lib2_name "$(BC_ENABLED_NAME) && $(BC_ENABLE_EXTRA_MATH_NAME)" 1
|
||||
|
||||
OBJS1 = $(OBJ) $(DC_OBJ) $(BC_OBJ) $(HISTORY_OBJ) $(RAND_OBJ) $(BC_HELP_O) $(DC_HELP_O)
|
||||
OBJS = $(OBJS1) $(BC_LIB_O) $(BC_LIB2_O) $(BC_LIB3_O)
|
||||
OBJ_TARGETS1 = $(DC_HELP_O) $(BC_HELP_O) $(BC_LIB_O) $(BC_LIB2_O) $(BC_LIB3_O)
|
||||
OBJ_TARGETS = $(OBJ_TARGETS1) $(BC_OBJ) $(DC_OBJ) $(HISTORY_OBJ) $(RAND_OBJ) $(OBJ)
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
all: make_bin $(OBJ_TARGETS)
|
||||
$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC)
|
||||
%%LINK%%
|
||||
|
||||
$(GEN_EXEC):
|
||||
%%GEN_EXEC_TARGET%%
|
||||
|
||||
$(BC_LIB_C): $(GEN_EXEC) $(BC_LIB)
|
||||
$(GEN_EMU) $(GEN_EXEC) $(BC_LIB) $(BC_LIB_C) $(BC_LIB_C_ARGS)
|
||||
|
||||
$(BC_LIB2_C): $(GEN_EXEC) $(BC_LIB2)
|
||||
$(GEN_EMU) $(GEN_EXEC) $(BC_LIB2) $(BC_LIB2_C) $(BC_LIB2_C_ARGS)
|
||||
|
||||
$(BC_HELP_C): $(GEN_EXEC) $(BC_HELP)
|
||||
$(GEN_EMU) $(GEN_EXEC) $(BC_HELP) $(BC_HELP_C) bc_help bc.h "" $(BC_ENABLED_NAME)
|
||||
|
||||
$(DC_HELP_C): $(GEN_EXEC) $(DC_HELP)
|
||||
$(GEN_EMU) $(GEN_EXEC) $(DC_HELP) $(DC_HELP_C) dc_help dc.h "" $(DC_ENABLED_NAME)
|
||||
|
||||
make_bin:
|
||||
$(MKDIR) -p $(BIN)
|
||||
|
||||
help:
|
||||
@printf 'available targets:\n'
|
||||
@printf '\n'
|
||||
@printf ' all (default) builds %%EXECUTABLES%%\n'
|
||||
@printf ' check alias for `make test`\n'
|
||||
@printf ' clean removes all build files\n'
|
||||
@printf ' clean_config removes all build files as well as the generated Makefile\n'
|
||||
@printf ' clean_tests removes all build files, the generated Makefile,\n'
|
||||
@printf ' and generated tests\n'
|
||||
@printf ' install installs binaries to "%s%s"\n' "$(DESTDIR)" "$(BINDIR)"
|
||||
@printf ' and (if enabled) manpages to "%s%s"\n' "$(DESTDIR)" "$(MAN1DIR)"
|
||||
@printf ' karatsuba runs the karatsuba script (requires Python 3)\n'
|
||||
@printf ' karatsuba_test runs the karatsuba script while running tests\n'
|
||||
@printf ' (requires Python 3)\n'
|
||||
@printf ' uninstall uninstalls binaries from "%s%s"\n' "$(DESTDIR)" "$(BINDIR)"
|
||||
@printf ' and (if enabled) manpages from "%s%s"\n' "$(DESTDIR)" "$(MAN1DIR)"
|
||||
@printf ' test runs the test suite\n'
|
||||
@printf ' test_bc runs the bc test suite, if bc has been built\n'
|
||||
@printf ' test_dc runs the dc test suite, if dc has been built\n'
|
||||
@printf ' time_test runs the test suite, displaying times for some things\n'
|
||||
@printf ' time_test_bc runs the bc test suite, displaying times for some things\n'
|
||||
@printf ' time_test_dc runs the dc test suite, displaying times for some things\n'
|
||||
@printf ' timeconst runs the test on the Linux timeconst.bc script,\n'
|
||||
@printf ' if it exists and bc has been built\n'
|
||||
@printf ' valgrind runs the test suite through valgrind\n'
|
||||
@printf ' valgrind_bc runs the bc test suite, if bc has been built,\n'
|
||||
@printf ' through valgrind\n'
|
||||
@printf ' valgrind_dc runs the dc test suite, if dc has been built,\n'
|
||||
@printf ' through valgrind\n'
|
||||
|
||||
check: test
|
||||
|
||||
test: test_bc timeconst test_dc
|
||||
|
||||
test_bc:
|
||||
%%BC_TEST%%
|
||||
|
||||
test_dc:
|
||||
%%DC_TEST%%
|
||||
|
||||
time_test: time_test_bc timeconst time_test_dc
|
||||
|
||||
time_test_bc:
|
||||
%%BC_TIME_TEST%%
|
||||
|
||||
time_test_dc:
|
||||
%%DC_TIME_TEST%%
|
||||
|
||||
timeconst:
|
||||
%%TIMECONST%%
|
||||
|
||||
valgrind: valgrind_bc valgrind_dc
|
||||
|
||||
valgrind_bc:
|
||||
%%VG_BC_TEST%%
|
||||
|
||||
valgrind_dc:
|
||||
%%VG_DC_TEST%%
|
||||
|
||||
karatsuba:
|
||||
%%KARATSUBA%%
|
||||
|
||||
karatsuba_test:
|
||||
%%KARATSUBA_TEST%%
|
||||
|
||||
coverage_output:
|
||||
%%COVERAGE_OUTPUT%%
|
||||
|
||||
coverage:%%COVERAGE_PREREQS%%
|
||||
|
||||
version:
|
||||
@printf '%s' "$(VERSION)"
|
||||
|
||||
libcname:
|
||||
@printf '%s' "$(BC_LIB_C)"
|
||||
|
||||
extra_math:
|
||||
@printf '%s' "$(BC_ENABLE_EXTRA_MATH)"
|
||||
|
||||
manpages:
|
||||
$(MANPAGE) $(BC_RONN) $(BC_MANPAGE)
|
||||
$(MANPAGE) $(DC_RONN) $(DC_MANPAGE)
|
||||
|
||||
clean_gen:
|
||||
@$(RM) -f $(GEN_EXEC)
|
||||
|
||||
clean:%%CLEAN_PREREQS%%
|
||||
@printf 'Cleaning files...\n'
|
||||
@$(RM) -f $(OBJ)
|
||||
@$(RM) -f $(BC_OBJ)
|
||||
@$(RM) -f $(DC_OBJ)
|
||||
@$(RM) -f $(HISTORY_OBJ)
|
||||
@$(RM) -f $(RAND_OBJ)
|
||||
@$(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)
|
||||
|
||||
clean_config: clean
|
||||
@printf 'Cleaning config...\n'
|
||||
@$(RM) -f Makefile
|
||||
|
||||
clean_coverage:
|
||||
@printf 'Cleaning coverage files...\n'
|
||||
@$(RM) -f *.gcov
|
||||
@$(RM) -f *.html
|
||||
@$(RM) -f *.gcda *.gcno
|
||||
@$(RM) -f *.profraw
|
||||
@$(RM) -f $(GCDA) $(GCNO)
|
||||
@$(RM) -f $(BC_GCDA) $(BC_GCNO)
|
||||
@$(RM) -f $(DC_GCDA) $(DC_GCNO)
|
||||
@$(RM) -f $(HISTORY_GCDA) $(HISTORY_GCNO)
|
||||
@$(RM) -f $(RAND_GCDA) $(RAND_GCNO)
|
||||
@$(RM) -f $(BC_LIB_GCDA) $(BC_LIB_GCNO)
|
||||
@$(RM) -f $(BC_LIB2_GCDA) $(BC_LIB2_GCNO)
|
||||
@$(RM) -f $(BC_HELP_GCDA) $(BC_HELP_GCNO)
|
||||
@$(RM) -f $(DC_HELP_GCDA) $(DC_HELP_GCNO)
|
||||
|
||||
clean_tests: clean clean_config clean_coverage
|
||||
@printf 'Cleaning test files...\n'
|
||||
@$(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/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/dc/scripts/prime.txt tests/dc/scripts/stream.txt
|
||||
@$(RM) -f .log_*.txt
|
||||
@$(RM) -f .math.txt .results.txt .ops.txt
|
||||
@$(RM) -f .test.txt
|
||||
@$(RM) -f tags .gdbbreakpoints .gdb_history .gdbsetup
|
||||
@$(RM) -f cscope.*
|
||||
@$(RM) -f bc.old
|
||||
|
||||
install_locales:
|
||||
$(LOCALE_INSTALL) $(NLSPATH) $(MAIN_EXEC) $(DESTDIR)
|
||||
|
||||
install_bc_manpage:
|
||||
$(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(BC_MANPAGE) $(DESTDIR)$(MAN1DIR)/$(BC_MANPAGE_NAME)
|
||||
|
||||
install_dc_manpage:
|
||||
$(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(DC_MANPAGE) $(DESTDIR)$(MAN1DIR)/$(DC_MANPAGE_NAME)
|
||||
|
||||
install:%%INSTALL_LOCALES_PREREQS%%%%INSTALL_PREREQS%%
|
||||
$(INSTALL) $(DESTDIR)$(BINDIR) "$(EXEC_SUFFIX)"
|
||||
|
||||
uninstall_locales:
|
||||
$(LOCALE_UNINSTALL) $(NLSPATH) $(MAIN_EXEC) $(DESTDIR)
|
||||
|
||||
uninstall_bc_manpage:
|
||||
$(RM) -f $(DESTDIR)$(MAN1DIR)/$(BC_MANPAGE_NAME)
|
||||
|
||||
uninstall_bc:
|
||||
$(RM) -f $(DESTDIR)$(BINDIR)/$(EXEC_PREFIX)$(BC)$(EXEC_SUFFIX)
|
||||
|
||||
uninstall_dc_manpage:
|
||||
$(RM) -f $(DESTDIR)$(MAN1DIR)/$(DC_MANPAGE_NAME)
|
||||
|
||||
uninstall_dc:
|
||||
$(RM) -f $(DESTDIR)$(BINDIR)/$(EXEC_PREFIX)$(DC)$(EXEC_SUFFIX)
|
||||
|
||||
uninstall:%%UNINSTALL_LOCALES_PREREQS%%%%UNINSTALL_MAN_PREREQS%%%%UNINSTALL_PREREQS%%
|
824
NEWS.md
Normal file
824
NEWS.md
Normal file
@ -0,0 +1,824 @@
|
||||
# News
|
||||
|
||||
## 3.0.2
|
||||
|
||||
This is a production release that adds `utf8` locale symlinks and removes an
|
||||
unused `auto` variable from the `ceil()` function in the [extended math
|
||||
library][16].
|
||||
|
||||
Users do ***NOT*** need to update unless they want the locales.
|
||||
|
||||
## 3.0.1
|
||||
|
||||
This is a production release with two small changes. Users do ***NOT*** need to
|
||||
upgrade to this release; however, if they haven't upgraded to `3.0.0` yet, it
|
||||
may be worthwhile to upgrade to this release.
|
||||
|
||||
The first change is fixing a compiler warning on FreeBSD with strict warnings
|
||||
on.
|
||||
|
||||
The second change is to make the new implementation of `ceil()` in `lib2.bc`
|
||||
much more efficient.
|
||||
|
||||
## 3.0.0
|
||||
|
||||
*Notes for package maintainers:*
|
||||
|
||||
*First, the `2.7.0` release series saw a change in the option parsing. This made
|
||||
me change one error message and add a few others. The error message that was
|
||||
changed removed one format specifier. This means that `printf()` will seqfault
|
||||
on old locale files. Unfortunately, `bc` cannot use any locale files except the
|
||||
global ones that are already installed, so it will use the previous ones while
|
||||
running tests during install. **If `bc` segfaults while running arg tests when
|
||||
updating, it is because the global locale files have not been replaced. Make
|
||||
sure to either prevent the test suite from running on update or remove the old
|
||||
locale files before updating.** Once this is done, `bc` should install without
|
||||
problems.*
|
||||
|
||||
*Second, **the option to build without signal support has been removed**. See
|
||||
below for the reasons why.*
|
||||
|
||||
This is a production release with some small bug fixes, a few improvements,
|
||||
three major bug fixes, and a complete redesign of `bc`'s error and signal
|
||||
handling. **Users and package maintainers should update to this version as soon
|
||||
as possible.**
|
||||
|
||||
The first major bug fix was in how `bc` executed files. Previously, a whole file
|
||||
was parsed before it was executed, but if a function is defined *after* code,
|
||||
especially if the function definition was actually a redefinition, and the code
|
||||
before the definition referred to the previous function, this `bc` would replace
|
||||
the function before executing any code. The fix was to make sure that all code
|
||||
that existed before a function definition was executed.
|
||||
|
||||
The second major bug fix was in `bc`'s `lib2.bc`. The `ceil()` function had a
|
||||
bug where a `0` in the decimal place after the truncation position, caused it to
|
||||
output the wrong numbers if there was any non-zero digit after.
|
||||
|
||||
The third major bug is that when passing parameters to functions, if an
|
||||
expression included an array (not an array element) as a parameter, it was
|
||||
accepted, when it should have been rejected. It is now correctly rejected.
|
||||
|
||||
Beyond that, this `bc` got several improvements that both sped it up, improved
|
||||
the handling of signals, and improved the error handling.
|
||||
|
||||
First, the requirements for `bc` were pushed back to POSIX 2008. `bc` uses one
|
||||
function, `strdup()`, which is not in POSIX 2001, and it is in the X/Open System
|
||||
Interfaces group 2001. It is, however, in POSIX 2008, and since POSIX 2008 is
|
||||
old enough to be supported anywhere that I care, that should be the requirement.
|
||||
|
||||
Second, the BcVm global variable was put into `bss`. This actually slightly
|
||||
reduces the size of the executable from a massive code shrink, and it will stop
|
||||
`bc` from allocating a large set of memory when `bc` starts.
|
||||
|
||||
Third, the default Karatsuba length was updated from 64 to 32 after making the
|
||||
optimization changes below, since 32 is going to be better than 64 after the
|
||||
changes.
|
||||
|
||||
Fourth, Spanish translations were added.
|
||||
|
||||
Fifth, the interpreter received a speedup to make performance on non-math-heavy
|
||||
scripts more competitive with GNU `bc`. While improvements did, in fact, get it
|
||||
much closer (see the [benchmarks][19]), it isn't quite there.
|
||||
|
||||
There were several things done to speed up the interpreter:
|
||||
|
||||
First, several small inefficiencies were removed. These inefficiencies included
|
||||
calling the function `bc_vec_pop(v)` twice instead of calling
|
||||
`bc_vec_npop(v, 2)`. They also included an extra function call for checking the
|
||||
size of the stack and checking the size of the stack more than once on several
|
||||
operations.
|
||||
|
||||
Second, since the current `bc` function is the one that stores constants and
|
||||
strings, the program caches pointers to the current function's vectors of
|
||||
constants and strings to prevent needing to grab the current function in order
|
||||
to grab a constant or a string.
|
||||
|
||||
Third, `bc` tries to reuse `BcNum`'s (the internal representation of
|
||||
arbitary-precision numbers). If a `BcNum` has the default capacity of
|
||||
`BC_NUM_DEF_SIZE` (32 on 64-bit and 16 on 32-bit) when it is freed, it is added
|
||||
to a list of available `BcNum`'s. And then, when a `BcNum` is allocated with a
|
||||
capacity of `BC_NUM_DEF_SIZE` and any `BcNum`'s exist on the list of reusable
|
||||
ones, one of those ones is grabbed instead.
|
||||
|
||||
In order to support these changes, the `BC_NUM_DEF_SIZE` was changed. It used to
|
||||
be 16 bytes on all systems, but it was changed to more closely align with the
|
||||
minimum allocation size on Linux, which is either 32 bytes (64-bit musl), 24
|
||||
bytes (64-bit glibc), 16 bytes (32-bit musl), or 12 bytes (32-bit glibc). Since
|
||||
these are the minimum allocation sizes, these are the sizes that would be
|
||||
allocated anyway, making it worth it to just use the whole space, so the value
|
||||
of `BC_NUM_DEF_SIZE` on 64-bit systems was changed to 32 bytes.
|
||||
|
||||
On top of that, at least on 64-bit, `BC_NUM_DEF_SIZE` supports numbers with
|
||||
either 72 integer digits or 45 integer digits and 27 fractional digits. This
|
||||
should be more than enough for most cases since `bc`'s default `scale` values
|
||||
are 0 or 20, meaning that, by default, it has at most 20 fractional digits. And
|
||||
45 integer digits are *a lot*; it's enough to calculate the amount of mass in
|
||||
the Milky Way galaxy in kilograms. Also, 72 digits is enough to calculate the
|
||||
diameter of the universe in Planck lengths.
|
||||
|
||||
(For 32-bit, these numbers are either 32 integer digits or 12 integer digits and
|
||||
20 fractional digits. These are also quite big, and going much bigger on a
|
||||
32-bit system seems a little pointless since 12 digits in just under a trillion
|
||||
and 20 fractional digits is still enough for about any use since `10^-20` light
|
||||
years is just under a millimeter.)
|
||||
|
||||
All of this together means that for ordinary uses, and even uses in scientific
|
||||
work, the default number size will be all that is needed, which means that
|
||||
nearly all, if not all, numbers will be reused, relieving pressure on the system
|
||||
allocator.
|
||||
|
||||
I did several experiments to find the changes that had the most impact,
|
||||
especially with regard to reusing `BcNum`'s. One was putting `BcNum`'s into
|
||||
buckets according to their capacity in powers of 2 up to 512. That performed
|
||||
worse than `bc` did in `2.7.2`. Another was putting any `BcNum` on the reuse
|
||||
list that had a capacity of `BC_NUM_DEF_SIZE * 2` and reusing them for `BcNum`'s
|
||||
that requested `BC_NUM_DEF_SIZE`. This did reduce the amount of time spent, but
|
||||
it also spent a lot of time in the system allocator for an unknown reason. (When
|
||||
using `strace`, a bunch more `brk` calls showed up.) Just reusing `BcNum`'s that
|
||||
had exactly `BC_NUM_DEF_SIZE` capacity spent the smallest amount of time in both
|
||||
user and system time. This makes sense, especially with the changes to make
|
||||
`BC_NUM_DEF_SIZE` bigger on 64-bit systems, since the vast majority of numbers
|
||||
will only ever use numbers with a size less than or equal to `BC_NUM_DEF_SIZE`.
|
||||
|
||||
Last of all, `bc`'s signal handling underwent a complete redesign. (This is the
|
||||
reason that this version is `3.0.0` and not `2.8.0`.) The change was to move
|
||||
from a polling approach to signal handling to an interrupt-based approach.
|
||||
|
||||
Previously, every single loop condition had a check for signals. I suspect that
|
||||
this could be expensive when in tight loops.
|
||||
|
||||
Now, the signal handler just uses `longjmp()` (actually `siglongjmp()`) to start
|
||||
an unwinding of the stack until it is stopped or the stack is unwound to
|
||||
`main()`, which just returns. If `bc` is currently executing code that cannot be
|
||||
safely interrupted (according to POSIX), then signals are "locked." The signal
|
||||
handler checks if the lock is taken, and if it is, it just sets the status to
|
||||
indicate that a signal arrived. Later, when the signal lock is released, the
|
||||
status is checked to see if a signal came in. If so, the stack unwinding starts.
|
||||
|
||||
This design eliminates polling in favor of maintaining a stack of `jmp_buf`'s.
|
||||
This has its own performance implications, but it gives better interaction. And
|
||||
the cost of pushing and popping a `jmp_buf` in a function is paid at most twice.
|
||||
Most functions do not pay that price, and most of the rest only pay it once.
|
||||
(There are only some 3 functions in `bc` that push and pop a `jmp_buf` twice.)
|
||||
|
||||
As a side effect of this change, I had to eliminate the use of `stdio.h` in `bc`
|
||||
because `stdio` does not play nice with signals and `longjmp()`. I implemented
|
||||
custom I/O buffer code that takes a fraction of the size. This means that static
|
||||
builds will be smaller, but non-static builds will be bigger, though they will
|
||||
have less linking time.
|
||||
|
||||
This change is also good because my history implementation was already bypassing
|
||||
`stdio` for good reasons, and unifying the architecture was a win.
|
||||
|
||||
Another reason for this change is that my `bc` should *always* behave correctly
|
||||
in the presence of signals like `SIGINT`, `SIGTERM`, and `SIGQUIT`. With the
|
||||
addition of my own I/O buffering, I needed to also make sure that the buffers
|
||||
were correctly flushed even when such signals happened.
|
||||
|
||||
For this reason, I **removed the option to build without signal support**.
|
||||
|
||||
As a nice side effect of this change, the error handling code could be changed
|
||||
to take advantage of the stack unwinding that signals used. This means that
|
||||
signals and error handling use the same code paths, which means that the stack
|
||||
unwinding is well-tested. (Errors are tested heavily in the test suite.)
|
||||
|
||||
It also means that functions do not need to return a status code that
|
||||
***every*** caller needs to check. This eliminated over 100 branches that simply
|
||||
checked return codes and then passed that return code up the stack if necessary.
|
||||
The code bloat savings from this is at least 1700 bytes on `x86_64`, *before*
|
||||
taking into account the extra code from removing `stdio.h`.
|
||||
|
||||
## 2.7.2
|
||||
|
||||
This is a production release with one major bug fix.
|
||||
|
||||
The `length()` built-in function can take either a number or an array. If it
|
||||
takes an array, it returns the length of the array. Arrays can be passed by
|
||||
reference. The bug is that the `length()` function would not properly
|
||||
dereference arrays that were references. This is a bug that affects all users.
|
||||
|
||||
**ALL USERS SHOULD UPDATE `bc`**.
|
||||
|
||||
## 2.7.1
|
||||
|
||||
This is a production release with fixes for new locales and fixes for compiler
|
||||
warnings on FreeBSD.
|
||||
|
||||
## 2.7.0
|
||||
|
||||
This is a production release with a bug fix for Linux, new translations, and new
|
||||
features.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* Option parsing in `BC_ENV_ARGS` was broken on Linux in 2.6.1 because `glibc`'s
|
||||
`getopt_long()` is broken. To get around that, and to support long options on
|
||||
every platform, an adapted version of [`optparse`][17] was added. Now, `bc`
|
||||
does not even use `getopt()`.
|
||||
* Parsing `BC_ENV_ARGS` with quotes now works. It isn't the smartest, but it
|
||||
does the job if there are spaces in file names.
|
||||
|
||||
The following new languages are supported:
|
||||
|
||||
* Dutch
|
||||
* Polish
|
||||
* Russian
|
||||
* Japanes
|
||||
* Simplified Chinese
|
||||
|
||||
All of these translations were generated using [DeepL][18], so improvements are
|
||||
welcome.
|
||||
|
||||
There is only one new feature: **`bc` now has a built-in pseudo-random number
|
||||
generator** (PRNG).
|
||||
|
||||
The PRNG is seeded, making it useful for applications where
|
||||
`/dev/urandom` does not work because output needs to be reproducible. However,
|
||||
it also uses `/dev/urandom` to seed itself by default, so it will start with a
|
||||
good seed by default.
|
||||
|
||||
It also outputs 32 bits on 32-bit platforms and 64 bits on 64-bit platforms, far
|
||||
better than the 15 bits of C's `rand()` and `bash`'s `$RANDOM`.
|
||||
|
||||
In addition, the PRNG can take a bound, and when it gets a bound, it
|
||||
automatically adjusts to remove bias. It can also generate numbers of arbitrary
|
||||
size. (As of the time of release, the largest pseudo-random number generated by
|
||||
this `bc` was generated with a bound of `2^(2^20)`.)
|
||||
|
||||
***IMPORTANT: read the [`bc` manual][9] and the [`dc` manual][10] to find out
|
||||
exactly what guarantees the PRNG provides. The underlying implementation is not
|
||||
guaranteed to stay the same, but the guarantees that it provides are guaranteed
|
||||
to stay the same regardless of the implementation.***
|
||||
|
||||
On top of that, four functions were added to `bc`'s [extended math library][16]
|
||||
to make using the PRNG easier:
|
||||
|
||||
* `frand(p)`: Generates a number between `[0,1)` to `p` decimal places.
|
||||
* `ifrand(i, p)`: Generates an integer with bound `i` and adds it to `frand(p)`.
|
||||
* `srand(x)`: Randomizes the sign of `x`. In other words, it flips the sign of
|
||||
`x` with probability `0.5`.
|
||||
* `brand()`: Returns a random boolean value (either `0` or `1`).
|
||||
|
||||
## 2.6.1
|
||||
|
||||
This is a production release with a bug fix for FreeBSD.
|
||||
|
||||
The bug was that when `bc` was built without long options, it would give a fatal
|
||||
error on every run. This was caused by a mishandling of `optind`.
|
||||
|
||||
## 2.6.0
|
||||
|
||||
This release is a production release ***with no bugfixes***. If you do not want
|
||||
to upgrade, you don't have to.
|
||||
|
||||
No source code changed; the only thing that changed was `lib2.bc`.
|
||||
|
||||
This release adds one function to the [extended math library][16]: `p(x, y)`,
|
||||
which calculates `x` to the power of `y`, whether or not `y` is an integer. (The
|
||||
`^` operator can only accept integer powers.)
|
||||
|
||||
This release also includes a couple of small tweaks to the [extended math
|
||||
library][16], mostly to fix returning numbers with too high of `scale`.
|
||||
|
||||
## 2.5.3
|
||||
|
||||
This release is a production release which addresses inconsistencies in the
|
||||
Portuguese locales. No `bc` code was changed.
|
||||
|
||||
The issues were that the ISO files used different naming, and also that the
|
||||
files that should have been symlinks were not. I did not catch that because
|
||||
GitHub rendered them the exact same way.
|
||||
|
||||
## 2.5.2
|
||||
|
||||
This release is a production release.
|
||||
|
||||
No code was changed, but the build system was changed to allow `CFLAGS` to be
|
||||
given to `CC`, like this:
|
||||
|
||||
```
|
||||
CC="gcc -O3 -march=native" ./configure.sh
|
||||
```
|
||||
|
||||
If this happens, the flags are automatically put into `CFLAGS`, and the compiler
|
||||
is set appropriately. In the example above this means that `CC` will be "gcc"
|
||||
and `CFLAGS` will be "-O3 -march=native".
|
||||
|
||||
This behavior was added to conform to GNU autotools practices.
|
||||
|
||||
## 2.5.1
|
||||
|
||||
This is a production release which addresses portability concerns discovered
|
||||
in the `bc` build system. No `bc` code was changed.
|
||||
|
||||
* Support for Solaris SPARC and AIX were added.
|
||||
* Minor documentations edits were performed.
|
||||
* An option for `configure.sh` was added to disable long options if
|
||||
`getopt_long()` is missing.
|
||||
|
||||
## 2.5.0
|
||||
|
||||
This is a production release with new translations. No code changed.
|
||||
|
||||
The translations were contributed by [bugcrazy][15], and they are for
|
||||
Portuguese, both Portugal and Brazil locales.
|
||||
|
||||
## 2.4.0
|
||||
|
||||
This is a production release primarily aimed at improving `dc`.
|
||||
|
||||
* A couple of copy and paste errors in the [`dc` manual][10] were fixed.
|
||||
* `dc` startup was optimized by making sure it didn't have to set up `bc`-only
|
||||
things.
|
||||
* The `bc` `&&` and `||` operators were made available to `dc` through the `M`
|
||||
and `m` commands, respectively.
|
||||
* `dc` macros were changed to be tail call-optimized.
|
||||
|
||||
The last item, tail call optimization, means that if the last thing in a macro
|
||||
is a call to another macro, then the old macro is popped before executing the
|
||||
new macro. This change was made to stop `dc` from consuming more and more memory
|
||||
as macros are executed in a loop.
|
||||
|
||||
The `q` and `Q` commands still respect the "hidden" macros by way of recording
|
||||
how many macros were removed by tail call optimization.
|
||||
|
||||
## 2.3.2
|
||||
|
||||
This is a production release meant to fix warnings in the Gentoo `ebuild` by
|
||||
making it possible to disable binary stripping. Other users do *not* need to
|
||||
upgrade.
|
||||
|
||||
## 2.3.1
|
||||
|
||||
This is a production release. It fixes a bug that caused `-1000000000 < -1` to
|
||||
return `0`. This only happened with negative numbers and only if the value on
|
||||
the left was more negative by a certain amount. That said, this bug *is* a bad
|
||||
bug, and needs to be fixed.
|
||||
|
||||
**ALL USERS SHOULD UPDATE `bc`**.
|
||||
|
||||
## 2.3.0
|
||||
|
||||
This is a production release with changes to the build system.
|
||||
|
||||
## 2.2.0
|
||||
|
||||
This release is a production release. It only has new features and performance
|
||||
improvements.
|
||||
|
||||
1. The performance of `sqrt(x)` was improved.
|
||||
2. The new function `root(x, n)` was added to the extended math library to
|
||||
calculate `n`th roots.
|
||||
3. The new function `cbrt(x)` was added to the extended math library to
|
||||
calculate cube roots.
|
||||
|
||||
## 2.1.3
|
||||
|
||||
This is a non-critical release; it just changes the build system, and in
|
||||
non-breaking ways:
|
||||
|
||||
1. Linked locale files were changed to link to their sources with a relative
|
||||
link.
|
||||
2. A bug in `configure.sh` that caused long option parsing to fail under `bash`
|
||||
was fixed.
|
||||
|
||||
## 2.1.2
|
||||
|
||||
This release is not a critical release.
|
||||
|
||||
1. A few codes were added to history.
|
||||
2. Multiplication was optimized a bit more.
|
||||
3. Addition and subtraction were both optimized a bit more.
|
||||
|
||||
## 2.1.1
|
||||
|
||||
This release contains a fix for the test suite made for Linux from Scratch: now
|
||||
the test suite prints `pass` when a test is passed.
|
||||
|
||||
Other than that, there is no change in this release, so distros and other users
|
||||
do not need to upgrade.
|
||||
|
||||
## 2.1.0
|
||||
|
||||
This release is a production release.
|
||||
|
||||
The following bugs were fixed:
|
||||
|
||||
1. A `dc` bug that caused stack mishandling was fixed.
|
||||
2. A warning on OpenBSD was fixed.
|
||||
3. Bugs in `ctrl+arrow` operations in history were fixed.
|
||||
4. The ability to paste multiple lines in history was added.
|
||||
5. A `bc` bug, mishandling of array arguments to functions, was fixed.
|
||||
6. A crash caused by freeing the wrong pointer was fixed.
|
||||
7. A `dc` bug where strings, in a rare case, were mishandled in parsing was
|
||||
fixed.
|
||||
|
||||
In addition, the following changes were made:
|
||||
|
||||
1. Division was slightly optimized.
|
||||
2. An option was added to the build to disable printing of prompts.
|
||||
3. The special case of empty arguments is now handled. This is to prevent
|
||||
errors in scripts that end up passing empty arguments.
|
||||
4. A harmless bug was fixed. This bug was that, with the pop instructions
|
||||
(mostly) removed (see below), `bc` would leave extra values on its stack for
|
||||
`void` functions and in a few other cases. These extra items would not
|
||||
affect anything put on the stack and would not cause any sort of crash or
|
||||
even buggy behavior, but they would cause `bc` to take more memory than it
|
||||
needed.
|
||||
|
||||
On top of the above changes, the following optimizations were added:
|
||||
|
||||
1. The need for pop instructions in `bc` was removed.
|
||||
2. Extra tests on every iteration of the interpreter loop were removed.
|
||||
3. Updating function and code pointers on every iteration of the interpreter
|
||||
loop was changed to only updating them when necessary.
|
||||
4. Extra assignments to pointers were removed.
|
||||
|
||||
Altogether, these changes sped up the interpreter by around 2x.
|
||||
|
||||
***NOTE***: This is the last release with new features because this `bc` is now
|
||||
considered complete. From now on, only bug fixes and new translations will be
|
||||
added to this `bc`.
|
||||
|
||||
## 2.0.3
|
||||
|
||||
This is a production, bug-fix release.
|
||||
|
||||
Two bugs were fixed in this release:
|
||||
|
||||
1. A rare and subtle signal handling bug was fixed.
|
||||
2. A misbehavior on `0` to a negative power was fixed.
|
||||
|
||||
The last bug bears some mentioning.
|
||||
|
||||
When I originally wrote power, I did not thoroughly check its error cases;
|
||||
instead, I had it check if the first number was `0` and then if so, just return
|
||||
`0`. However, `0` to a negative power means that `1` will be divided by `0`,
|
||||
which is an error.
|
||||
|
||||
I caught this, but only after I stopped being cocky. You see, sometime later, I
|
||||
had noticed that GNU `bc` returned an error, correctly, but I thought it was
|
||||
wrong simply because that's not what my `bc` did. I saw it again later and had a
|
||||
double take. I checked for real, finally, and found out that my `bc` was wrong
|
||||
all along.
|
||||
|
||||
That was bad on me. But the bug was easy to fix, so it is fixed now.
|
||||
|
||||
There are two other things in this release:
|
||||
|
||||
1. Subtraction was optimized by [Stefan Eßer][14].
|
||||
2. Division was also optimized, also by Stefan Eßer.
|
||||
|
||||
## 2.0.2
|
||||
|
||||
This release contains a fix for a possible overflow in the signal handling. I
|
||||
would be surprised if any users ran into it because it would only happen after 2
|
||||
billion (`2^31-1`) `SIGINT`'s, but I saw it and had to fix it.
|
||||
|
||||
## 2.0.1
|
||||
|
||||
This release contains very few things that will apply to any users.
|
||||
|
||||
1. A slight bug in `dc`'s interactive mode was fixed.
|
||||
2. A bug in the test suite that was only triggered on NetBSD was fixed.
|
||||
3. **The `-P`/`--no-prompt` option** was added for users that do not want a
|
||||
prompt.
|
||||
4. A `make check` target was added as an alias for `make test`.
|
||||
5. `dc` got its own read prompt: `?> `.
|
||||
|
||||
## 2.0.0
|
||||
|
||||
This release is a production release.
|
||||
|
||||
This release is also a little different from previous releases. From here on
|
||||
out, I do not plan on adding any more features to this `bc`; I believe that it
|
||||
is complete. However, there may be bug fix releases in the future, if I or any
|
||||
others manage to find bugs.
|
||||
|
||||
This release has only a few new features:
|
||||
|
||||
1. `atan2(y, x)` was added to the extended math library as both `a2(y, x)` and
|
||||
`atan2(y, x)`.
|
||||
2. Locales were fixed.
|
||||
3. A **POSIX shell-compatible script was added as an alternative to compiling
|
||||
`gen/strgen.c`** on a host machine. More details about making the choice
|
||||
between the two can be found by running `./configure.sh --help` or reading
|
||||
the [build manual][13].
|
||||
4. Multiplication was optimized by using **diagonal multiplication**, rather
|
||||
than straight brute force.
|
||||
5. The `locale_install.sh` script was fixed.
|
||||
6. `dc` was given the ability to **use the environment variable
|
||||
`DC_ENV_ARGS`**.
|
||||
7. `dc` was also given the ability to **use the `-i` or `--interactive`**
|
||||
options.
|
||||
8. Printing the prompt was fixed so that it did not print when it shouldn't.
|
||||
9. Signal handling was fixed.
|
||||
10. **Handling of `SIGTERM` and `SIGQUIT`** was fixed.
|
||||
11. The **built-in functions `maxibase()`, `maxobase()`, and `maxscale()`** (the
|
||||
commands `T`, `U`, `V` in `dc`, respectively) were added to allow scripts to
|
||||
query for the max allowable values of those globals.
|
||||
12. Some incompatibilities with POSIX were fixed.
|
||||
|
||||
In addition, this release is `2.0.0` for a big reason: the internal format for
|
||||
numbers changed. They used to be a `char` array. Now, they are an array of
|
||||
larger integers, packing more decimal digits into each integer. This has
|
||||
delivered ***HUGE*** performance improvements, especially for multiplication,
|
||||
division, and power.
|
||||
|
||||
This `bc` should now be the fastest `bc` available, but I may be wrong.
|
||||
|
||||
## 1.2.8
|
||||
|
||||
This release contains a fix for a harmless bug (it is harmless in that it still
|
||||
works, but it just copies extra data) in the [`locale_install.sh`][12] script.
|
||||
|
||||
## 1.2.7
|
||||
|
||||
This version contains fixes for the build on Arch Linux.
|
||||
|
||||
## 1.2.6
|
||||
|
||||
This release removes the use of `local` in shell scripts because it's not POSIX
|
||||
shell-compatible, and also updates a man page that should have been updated a
|
||||
long time ago but was missed.
|
||||
|
||||
## 1.2.5
|
||||
|
||||
This release contains some missing locale `*.msg` files.
|
||||
|
||||
## 1.2.4
|
||||
|
||||
This release contains a few bug fixes and new French translations.
|
||||
|
||||
## 1.2.3
|
||||
|
||||
This release contains a fix for a bug: use of uninitialized data. Such data was
|
||||
only used when outputting an error message, but I am striving for perfection. As
|
||||
Michelangelo said, "Trifles make perfection, and perfection is no trifle."
|
||||
|
||||
## 1.2.2
|
||||
|
||||
This release contains fixes for OpenBSD.
|
||||
|
||||
## 1.2.1
|
||||
|
||||
This release contains bug fixes for some rare bugs.
|
||||
|
||||
## 1.2.0
|
||||
|
||||
This is a production release.
|
||||
|
||||
There have been several changes since `1.1.0`:
|
||||
|
||||
1. The build system had some changes.
|
||||
2. Locale support has been added. (Patches welcome for translations.)
|
||||
3. **The ability to turn `ibase`, `obase`, and `scale` into stacks** was added
|
||||
with the `-g` command-line option. (See the [`bc` manual][9] for more
|
||||
details.)
|
||||
4. Support for compiling on Mac OSX out of the box was added.
|
||||
5. The extended math library got `t(x)`, `ceil(x)`, and some aliases.
|
||||
6. The extended math library also got `r2d(x)` (for converting from radians to
|
||||
degrees) and `d2r(x)` (for converting from degrees to radians). This is to
|
||||
allow using degrees with the standard library.
|
||||
7. Both calculators now accept numbers in **scientific notation**. See the
|
||||
[`bc` manual][9] and the [`dc` manual][10] for details.
|
||||
8. Both calculators can **output in either scientific or engineering
|
||||
notation**. See the [`bc` manual][9] and the [`dc` manual][10] for details.
|
||||
9. Some inefficiencies were removed.
|
||||
10. Some bugs were fixed.
|
||||
11. Some bugs in the extended library were fixed.
|
||||
12. Some defects from [Coverity Scan][11] were fixed.
|
||||
|
||||
## 1.1.4
|
||||
|
||||
This release contains a fix to the build system that allows it to build on older
|
||||
versions of `glibc`.
|
||||
|
||||
## 1.1.3
|
||||
|
||||
This release contains a fix for a bug in the test suite where `bc` tests and
|
||||
`dc` tests could not be run in parallel.
|
||||
|
||||
## 1.1.2
|
||||
|
||||
This release has a fix for a history bug; the down arrow did not work.
|
||||
|
||||
## 1.1.1
|
||||
|
||||
This release fixes a bug in the `1.1.0` build system. The source is exactly the
|
||||
same.
|
||||
|
||||
The bug that was fixed was a failure to install if no `EXECSUFFIX` was used.
|
||||
|
||||
## 1.1.0
|
||||
|
||||
This is a production release. However, many new features were added since `1.0`.
|
||||
|
||||
1. **The build system has been changed** to use a custom, POSIX
|
||||
shell-compatible configure script ([`configure.sh`][6]) to generate a POSIX
|
||||
make-compatible `Makefile`, which means that `bc` and `dc` now build out of
|
||||
the box on any POSIX-compatible system.
|
||||
2. Out-of-memory and output errors now cause the `bc` to report the error,
|
||||
clean up, and die, rather than just reporting and trying to continue.
|
||||
3. **Strings and constants are now garbage collected** when possible.
|
||||
4. Signal handling and checking has been made more simple and more thorough.
|
||||
5. `BcGlobals` was refactored into `BcVm` and `BcVm` was made global. Some
|
||||
procedure names were changed to reflect its difference to everything else.
|
||||
6. Addition got a speed improvement.
|
||||
7. Some common code for addition and multiplication was refactored into its own
|
||||
procedure.
|
||||
8. A bug was removed where `dc` could have been selected, but the internal
|
||||
`#define` that returned `true` for a query about `dc` would not have
|
||||
returned `true`.
|
||||
9. Useless calls to `bc_num_zero()` were removed.
|
||||
10. **History support was added.** The history support is based off of a
|
||||
[UTF-8 aware fork][7] of [`linenoise`][8], which has been customized with
|
||||
`bc`'s own data structures and signal handling.
|
||||
11. Generating C source from the math library now removes tabs from the library,
|
||||
shrinking the size of the executable.
|
||||
12. The math library was shrunk.
|
||||
13. Error handling and reporting was improved.
|
||||
14. Reallocations were reduced by giving access to the request size for each
|
||||
operation.
|
||||
15. **`abs()` (`b` command for `dc`) was added as a builtin.**
|
||||
16. Both calculators were tested on FreeBSD.
|
||||
17. Many obscure parse bugs were fixed.
|
||||
18. Markdown and man page manuals were added, and the man pages are installed by
|
||||
`make install`.
|
||||
19. Executable size was reduced, though the added features probably made the
|
||||
executable end up bigger.
|
||||
20. **GNU-style array references were added as a supported feature.**
|
||||
21. Allocations were reduced.
|
||||
22. **New operators were added**: `$` (`$` for `dc`), `@` (`@` for `dc`), `@=`,
|
||||
`<<` (`H` for `dc`), `<<=`, `>>` (`h` for `dc`), and `>>=`. See the
|
||||
[`bc` manual][9] and the [`dc` manual][10] for more details.
|
||||
23. **An extended math library was added.** This library contains code that
|
||||
makes it so I can replace my desktop calculator with this `bc`. See the
|
||||
[`bc` manual][3] for more details.
|
||||
24. Support for all capital letters as numbers was added.
|
||||
25. **Support for GNU-style void functions was added.**
|
||||
26. A bug fix for improper handling of function parameters was added.
|
||||
27. Precedence for the or (`||`) operator was changed to match GNU `bc`.
|
||||
28. `dc` was given an explicit negation command.
|
||||
29. `dc` was changed to be able to handle strings in arrays.
|
||||
|
||||
## 1.1 Release Candidate 3
|
||||
|
||||
This release is the eighth release candidate for 1.1, though it is the third
|
||||
release candidate meant as a general release candidate. The new code has not
|
||||
been tested as thoroughly as it should for release.
|
||||
|
||||
## 1.1 Release Candidate 2
|
||||
|
||||
This release is the seventh release candidate for 1.1, though it is the second
|
||||
release candidate meant as a general release candidate. The new code has not
|
||||
been tested as thoroughly as it should for release.
|
||||
|
||||
## 1.1 FreeBSD Beta 5
|
||||
|
||||
This release is the sixth release candidate for 1.1, though it is the fifth
|
||||
release candidate meant specifically to test if `bc` works on FreeBSD. The new
|
||||
code has not been tested as thoroughly as it should for release.
|
||||
|
||||
## 1.1 FreeBSD Beta 4
|
||||
|
||||
This release is the fifth release candidate for 1.1, though it is the fourth
|
||||
release candidate meant specifically to test if `bc` works on FreeBSD. The new
|
||||
code has not been tested as thoroughly as it should for release.
|
||||
|
||||
## 1.1 FreeBSD Beta 3
|
||||
|
||||
This release is the fourth release candidate for 1.1, though it is the third
|
||||
release candidate meant specifically to test if `bc` works on FreeBSD. The new
|
||||
code has not been tested as thoroughly as it should for release.
|
||||
|
||||
## 1.1 FreeBSD Beta 2
|
||||
|
||||
This release is the third release candidate for 1.1, though it is the second
|
||||
release candidate meant specifically to test if `bc` works on FreeBSD. The new
|
||||
code has not been tested as thoroughly as it should for release.
|
||||
|
||||
## 1.1 FreeBSD Beta 1
|
||||
|
||||
This release is the second release candidate for 1.1, though it is meant
|
||||
specifically to test if `bc` works on FreeBSD. The new code has not been tested as
|
||||
thoroughly as it should for release.
|
||||
|
||||
## 1.1 Release Candidate 1
|
||||
|
||||
This is the first release candidate for 1.1. The new code has not been tested as
|
||||
thoroughly as it should for release.
|
||||
|
||||
## 1.0
|
||||
|
||||
This is the first non-beta release. `bc` is ready for production use.
|
||||
|
||||
As such, a lot has changed since 0.5.
|
||||
|
||||
1. `dc` has been added. It has been tested even more thoroughly than `bc` was
|
||||
for `0.5`. It does not have the `!` command, and for security reasons, it
|
||||
never will, so it is complete.
|
||||
2. `bc` has been more thoroughly tested. An entire section of the test suite
|
||||
(for both programs) has been added to test for errors.
|
||||
3. A prompt (`>>> `) has been added for interactive mode, making it easier to
|
||||
see inputs and outputs.
|
||||
4. Interrupt handling has been improved, including elimination of race
|
||||
conditions (as much as possible).
|
||||
5. MinGW and [Windows Subsystem for Linux][1] support has been added (see
|
||||
[xstatic][2] for binaries).
|
||||
6. Memory leaks and errors have been eliminated (as far as ASan and Valgrind
|
||||
can tell).
|
||||
7. Crashes have been eliminated (as far as [afl][3] can tell).
|
||||
8. Karatsuba multiplication was added (and thoroughly) tested, speeding up
|
||||
multiplication and power by orders of magnitude.
|
||||
9. Performance was further enhanced by using a "divmod" function to reduce
|
||||
redundant divisions and by removing superfluous `memset()` calls.
|
||||
10. To switch between Karatsuba and `O(n^2)` multiplication, the config variable
|
||||
`BC_NUM_KARATSUBA_LEN` was added. It is set to a sane default, but the
|
||||
optimal number can be found with [`karatsuba.py`][4] (requires Python 3)
|
||||
and then configured through `make`.
|
||||
11. The random math test generator script was changed to Python 3 and improved.
|
||||
`bc` and `dc` have together been run through 30+ million random tests.
|
||||
12. All known math bugs have been fixed, including out of control memory
|
||||
allocations in `sine` and `cosine` (that was actually a parse bug), certain
|
||||
cases of infinite loop on square root, and slight inaccuracies (as much as
|
||||
possible; see the [README][5]) in transcendental functions.
|
||||
13. Parsing has been fixed as much as possible.
|
||||
14. Test coverage was improved to 94.8%. The only paths not covered are ones
|
||||
that happen when `malloc()` or `realloc()` fails.
|
||||
15. An extension to get the length of an array was added.
|
||||
16. The boolean not (`!`) had its precedence change to match negation.
|
||||
17. Data input was hardened.
|
||||
18. `bc` was made fully compliant with POSIX when the `-s` flag is used or
|
||||
`POSIXLY_CORRECT` is defined.
|
||||
19. Error handling was improved.
|
||||
20. `bc` now checks that files it is given are not directories.
|
||||
|
||||
## 1.0 Release Candidate 7
|
||||
|
||||
This is the seventh release candidate for 1.0. It fixes a few bugs in 1.0
|
||||
Release Candidate 6.
|
||||
|
||||
## 1.0 Release Candidate 6
|
||||
|
||||
This is the sixth release candidate for 1.0. It fixes a few bugs in 1.0 Release
|
||||
Candidate 5.
|
||||
|
||||
## 1.0 Release Candidate 5
|
||||
|
||||
This is the fifth release candidate for 1.0. It fixes a few bugs in 1.0 Release
|
||||
Candidate 4.
|
||||
|
||||
## 1.0 Release Candidate 4
|
||||
|
||||
This is the fourth release candidate for 1.0. It fixes a few bugs in 1.0 Release
|
||||
Candidate 3.
|
||||
|
||||
## 1.0 Release Candidate 3
|
||||
|
||||
This is the third release candidate for 1.0. It fixes a few bugs in 1.0 Release
|
||||
Candidate 2.
|
||||
|
||||
## 1.0 Release Candidate 2
|
||||
|
||||
This is the second release candidate for 1.0. It fixes a few bugs in 1.0 Release
|
||||
Candidate 1.
|
||||
|
||||
## 1.0 Release Candidate 1
|
||||
|
||||
This is the first Release Candidate for 1.0. `bc` is complete, with `dc`, but it
|
||||
is not tested.
|
||||
|
||||
## 0.5
|
||||
|
||||
This beta release completes more features, but it is still not complete nor
|
||||
tested as thoroughly as necessary.
|
||||
|
||||
## 0.4.1
|
||||
|
||||
This beta release fixes a few bugs in 0.4.
|
||||
|
||||
## 0.4
|
||||
|
||||
This is a beta release. It does not have the complete set of features, and it is
|
||||
not thoroughly tested.
|
||||
|
||||
[1]: https://docs.microsoft.com/en-us/windows/wsl/install-win10
|
||||
[2]: https://pkg.musl.cc/bc/
|
||||
[3]: http://lcamtuf.coredump.cx/afl/
|
||||
[4]: ./karatsuba.py
|
||||
[5]: ./README.md
|
||||
[6]: ./configure.sh
|
||||
[7]: https://github.com/rain-1/linenoise-mob
|
||||
[8]: https://github.com/antirez/linenoise
|
||||
[9]: ./manuals/bc.1.ronn
|
||||
[10]: ./manuals/dc.1.ronn
|
||||
[11]: https://scan.coverity.com/projects/gavinhoward-bc
|
||||
[12]: ./locale_install.sh
|
||||
[13]: ./manuals/build.md
|
||||
[14]: https://github.com/stesser
|
||||
[15]: https://github.com/bugcrazy
|
||||
[16]: ./manuals/bc.1.ronn#extended-library
|
||||
[17]: https://github.com/skeeto/optparse
|
||||
[18]: https://www.deepl.com/translator
|
||||
[19]: ./manuals/benchmarks.md
|
14
NOTICE.md
Normal file
14
NOTICE.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Notice
|
||||
|
||||
Copyright 2018-2020 Gavin D. Howard and contributors.
|
||||
|
||||
## Contributors
|
||||
|
||||
The contributors to `bc` (besides Gavin) are listed below in alphabetical order.
|
||||
|
||||
* Laurent Bercot (skarnet)
|
||||
* Stefan Eßer (stesser)
|
||||
* Michael Forney (michaelforney)
|
||||
* John Regan (jprjr)
|
||||
* rofl0r
|
||||
* Zach van Rijn (me@zv.io)
|
332
README.md
Normal file
332
README.md
Normal file
@ -0,0 +1,332 @@
|
||||
# `bc`
|
||||
|
||||
[![Build Status][13]][14]
|
||||
[![codecov][15]][16]
|
||||
[![Coverity Scan Build Status][17]][18]
|
||||
|
||||
***WARNING: This project has moved to [https://git.yzena.com/][20] for [these
|
||||
reasons][21], though GitHub will remain a mirror.***
|
||||
|
||||
This is an implementation of the [POSIX `bc` calculator][12] that implements
|
||||
[GNU `bc`][1] extensions, as well as the period (`.`) extension for the BSD
|
||||
flavor of `bc`.
|
||||
|
||||
For more information, see this `bc`'s [full manual][2].
|
||||
|
||||
This `bc` also includes an implementation of `dc` in the same binary, accessible
|
||||
via a symbolic link, which implements all FreeBSD and GNU extensions. (If a
|
||||
standalone `dc` binary is desired, `bc` can be copied and renamed to `dc`.) The
|
||||
`!` command is omitted; I believe this poses security concerns and that such
|
||||
functionality is unnecessary.
|
||||
|
||||
For more information, see the `dc`'s [full manual][3].
|
||||
|
||||
This `bc` is Free and Open Source Software (FOSS). It is offered under the BSD
|
||||
2-clause License. Full license text may be found in the [`LICENSE.md`][4] file.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This `bc` only requires a C99-compatible compiler and a (mostly) POSIX
|
||||
2008-compatible system with the XSI (X/Open System Interfaces) option group.
|
||||
|
||||
Since POSIX 2008 with XSI requires the existence of a C99 compiler as `c99`, any
|
||||
POSIX and XSI-compatible system will have everything needed.
|
||||
|
||||
Systems that are known to work:
|
||||
|
||||
* Linux
|
||||
* FreeBSD
|
||||
* OpenBSD
|
||||
* NetBSD
|
||||
* Mac OSX
|
||||
* Solaris
|
||||
* AIX
|
||||
|
||||
Please submit bug reports if this `bc` does not build out of the box on any
|
||||
system besides Windows. If Windows binaries are needed, they can be found at
|
||||
[xstatic][6].
|
||||
|
||||
## Build
|
||||
|
||||
This `bc` should build unmodified on any POSIX-compliant system.
|
||||
|
||||
For more complex build requirements than the ones below, see the
|
||||
[build manual][5].
|
||||
|
||||
### Pre-built Binaries
|
||||
|
||||
It is possible to download pre-compiled binaries for a wide list of platforms,
|
||||
including Linux- and Windows-based systems, from [xstatic][6]. This link always
|
||||
points to the latest release of `bc`.
|
||||
|
||||
### Default
|
||||
|
||||
For the default build with optimization, use the following commands in the root
|
||||
directory:
|
||||
|
||||
```
|
||||
./configure.sh -O3
|
||||
make
|
||||
```
|
||||
|
||||
### One Calculator
|
||||
|
||||
To only build `bc`, use the following commands:
|
||||
|
||||
```
|
||||
./configure.sh --disable-dc
|
||||
make
|
||||
```
|
||||
|
||||
To only build `dc`, use the following commands:
|
||||
|
||||
```
|
||||
./configure.sh --disable-bc
|
||||
make
|
||||
```
|
||||
|
||||
### Debug
|
||||
|
||||
For debug builds, use the following commands in the root directory:
|
||||
|
||||
```
|
||||
./configure.sh -g
|
||||
make
|
||||
```
|
||||
|
||||
### Install
|
||||
|
||||
To install, use the following command:
|
||||
|
||||
```
|
||||
make install
|
||||
```
|
||||
|
||||
By default, `bc` and `dc` will be installed in `/usr/local`. For installing in
|
||||
other locations, use the `PREFIX` environment variable when running
|
||||
`configure.sh` or pass the `--prefix=<prefix>` option to `configure.sh`. See the
|
||||
[build manual][5], or run `./configure.sh --help`, for more details.
|
||||
|
||||
### Package and Distro Maintainers
|
||||
|
||||
#### Recommended Compiler
|
||||
|
||||
When I ran benchmarks with my `bc` compiled under `clang`, it performed much
|
||||
better than when compiled under `gcc`. I recommend compiling this `bc` with
|
||||
`clang`.
|
||||
|
||||
I also recommend building this `bc` with C11 if you can because `bc` will detect
|
||||
a C11 compiler and add `_Noreturn` to any relevant function(s).
|
||||
|
||||
#### Recommended Optimizations
|
||||
|
||||
I wrote this `bc` with Separation of Concerns, which means that there are many
|
||||
small functions that could be inlined. However, they are often called across
|
||||
file boundaries, and the default optimizer can only look at the current file,
|
||||
which means that they are not inlined.
|
||||
|
||||
Thus, because of the way this `bc` is built, it will automatically be slower
|
||||
than other `bc` implementations when running scripts with no math. (My `bc`'s
|
||||
math is *much* faster, so any non-trivial script should run faster in my `bc`.)
|
||||
|
||||
Some, or all, of the difference can be made up with the right optimizations. The
|
||||
optimizations I recommend are:
|
||||
|
||||
1. `-O3`
|
||||
2. `-flto` (link-time optimization)
|
||||
|
||||
in that order.
|
||||
|
||||
Link-time optimization, in particular, speeds up the `bc` a lot. This is because
|
||||
when link-time optimization is turned on, the optimizer can look across files
|
||||
and inline *much* more heavily.
|
||||
|
||||
However, I recommend ***NOT*** using `-march=native`. Doing so will reduce this
|
||||
`bc`'s performance, at least when building with link-time optimization. See the
|
||||
[benchmarks][19] for more details.
|
||||
|
||||
#### Stripping Binaries
|
||||
|
||||
By default, non-debug binaries are stripped, but stripping can be disabled with
|
||||
the `-T` option to `configure.sh`.
|
||||
|
||||
#### Using This `bc` as an Alternative
|
||||
|
||||
If this `bc` is packaged as an alternative to an already existing `bc` package,
|
||||
it is possible to rename it in the build to prevent name collision. To prepend
|
||||
to the name, just run the following:
|
||||
|
||||
```
|
||||
EXECPREFIX=<some_prefix> ./configure.sh
|
||||
```
|
||||
|
||||
To append to the name, just run the following:
|
||||
|
||||
```
|
||||
EXECSUFFIX=<some_suffix> ./configure.sh
|
||||
```
|
||||
|
||||
If a package maintainer wishes to add both a prefix and a suffix, that is
|
||||
allowed.
|
||||
|
||||
**Note**: The suggested name (and package name) when `bc` is not available is
|
||||
`bc-gh`.
|
||||
|
||||
#### Karatsuba Number
|
||||
|
||||
Package and distro maintainers have one tool at their disposal to build this
|
||||
`bc` in the optimal configuration: `karatsuba.py`.
|
||||
|
||||
This script is not a compile-time or runtime prerequisite; it is for package and
|
||||
distro maintainers to run once when a package is being created. It finds the
|
||||
optimal Karatsuba number (see the [algorithms manual][7] for more information)
|
||||
for the machine that it is running on.
|
||||
|
||||
The easiest way to run this script is with `make karatsuba`.
|
||||
|
||||
If desired, maintainers can also skip running this script because there is a
|
||||
sane default for the Karatsuba number.
|
||||
|
||||
## Status
|
||||
|
||||
This `bc` is robust.
|
||||
|
||||
It is well-tested, fuzzed, and fully standards-compliant (though not certified)
|
||||
with POSIX `bc`. The math has been tested with 40+ million random problems, so
|
||||
it is as correct as I can make it.
|
||||
|
||||
This `bc` can be used as a drop-in replacement for any existing `bc`. This `bc`
|
||||
is also compatible with MinGW toolchains, though history is not supported on
|
||||
Windows.
|
||||
|
||||
In addition, this `bc` is considered complete; i.e., there will be no more
|
||||
releases with additional features. However, it *is* actively maintained, so if
|
||||
any bugs are found, they will be fixed in new releases. Also, additional
|
||||
translations will also be added as they are provided.
|
||||
|
||||
## Comparison to GNU `bc`
|
||||
|
||||
This `bc` compares favorably to GNU `bc`.
|
||||
|
||||
* It has more extensions, which make this `bc` more useful for scripting.
|
||||
* This `bc` is a bit more POSIX compliant.
|
||||
* It has a much less buggy parser. The GNU `bc` will give parse errors for what
|
||||
is actually valid `bc` code, or should be. For example, putting an `else` on
|
||||
a new line after a brace can cause GNU `bc` to give a parse error.
|
||||
* This `bc` has fewer crashes.
|
||||
* GNU `bc` calculates the wrong number of significant digits for `length(x)`.
|
||||
* GNU `bc` will sometimes print numbers incorrectly. For example, when running
|
||||
it on the file `tests/bc/power.txt` in this repo, GNU `bc` gets all the right
|
||||
answers, but it fails to wrap the numbers at the proper place when outputting
|
||||
to a file.
|
||||
* This `bc` is faster. (See [Performance](#performance).)
|
||||
|
||||
### Performance
|
||||
|
||||
Because this `bc` packs more than `1` decimal digit per hardware integer, this
|
||||
`bc` is faster than GNU `bc` and can be *much* faster. Full benchmarks can be
|
||||
found at [manuals/benchmarks.md][19].
|
||||
|
||||
There is one instance where this `bc` is slower: if scripts are light on math.
|
||||
This is because this `bc`'s intepreter is slightly slower than GNU `bc`, but
|
||||
that is because it is more robust. See the [benchmarks][19].
|
||||
|
||||
## Algorithms
|
||||
|
||||
To see what algorithms this `bc` uses, see the [algorithms manual][7].
|
||||
|
||||
## Locales
|
||||
|
||||
Currently, this `bc` only has support for English (and US English), French,
|
||||
German, Portuguese, Dutch, Polish, Russian, Japanese, and Chinese locales.
|
||||
Patches are welcome for translations; use the existing `*.msg` files in
|
||||
`locales/` as a starting point.
|
||||
|
||||
In addition, patches for improvements are welcome; the last two messages in
|
||||
Portuguese were made with Google Translate, and the Dutch, Polish, Russian,
|
||||
Japanese, and Chinese locales were all generated with [DeepL][22].
|
||||
|
||||
The message files provided assume that locales apply to all regions where a
|
||||
language is used, but this might not be true for, e.g., `fr_CA` and `fr_CH`.
|
||||
Any corrections or a confirmation that the current texts are acceptable for
|
||||
those regions would be appreciated, too.
|
||||
|
||||
## Other Projects
|
||||
|
||||
Other projects based on this bc are:
|
||||
|
||||
* [busybox `bc`][8]. The busybox maintainers have made their own changes, so any
|
||||
bugs in the busybox `bc` should be reported to them.
|
||||
|
||||
* [toybox `bc`][9]. The maintainer has also made his own changes, so bugs in the
|
||||
toybox `bc` should be reported there.
|
||||
|
||||
## Language
|
||||
|
||||
This `bc` is written in pure ISO C99, using POSIX 2008 APIs.
|
||||
|
||||
## Commit Messages
|
||||
|
||||
This `bc` uses the commit message guidelines laid out in [this blog post][10].
|
||||
|
||||
## Semantic Versioning
|
||||
|
||||
This `bc` uses [semantic versioning][11].
|
||||
|
||||
## Contents
|
||||
|
||||
Items labeled with `(maintainer use only)` are not included in release source
|
||||
tarballs.
|
||||
|
||||
Files:
|
||||
|
||||
.gitignore The git ignore file (maintainer use only).
|
||||
.travis.yml The Travis CI file (maintainer use only).
|
||||
codecov.yml The Codecov file (maintainer use only).
|
||||
configure A symlink to configure.sh to make packaging easier.
|
||||
configure.sh The configure script.
|
||||
functions.sh A script with functions used by other scripts.
|
||||
install.sh Install script.
|
||||
karatsuba.py Script to find the optimal Karatsuba number.
|
||||
LICENSE.md A Markdown form of the BSD 2-clause License.
|
||||
link.sh A script to link dc to bc.
|
||||
locale_install.sh A script to install locales, if desired.
|
||||
locale_uninstall.sh A script to uninstall locales.
|
||||
Makefile.in The Makefile template.
|
||||
manpage.sh Script to generate man pages from ronn files.
|
||||
NOTICE.md List of contributors and copyright owners.
|
||||
RELEASE.md A checklist for making a release (maintainer use only).
|
||||
release.sh A script to test for release (maintainer use only).
|
||||
safe-install.sh Safe install script from musl libc.
|
||||
|
||||
Folders:
|
||||
|
||||
gen The bc math library, help texts, and code to generate C source.
|
||||
include All header files.
|
||||
locales Locale files, in .msg format. Patches welcome for translations.
|
||||
manuals Manuals for both programs.
|
||||
src All source code.
|
||||
tests All tests.
|
||||
|
||||
[1]: https://www.gnu.org/software/bc/
|
||||
[2]: ./manuals/bc.md
|
||||
[3]: ./manuals/dc.md
|
||||
[4]: ./LICENSE.md
|
||||
[5]: ./manuals/build.md
|
||||
[6]: https://pkg.musl.cc/bc/
|
||||
[7]: ./manuals/algorithms.md
|
||||
[8]: https://git.busybox.net/busybox/tree/miscutils/bc.c
|
||||
[9]: https://github.com/landley/toybox/blob/master/toys/pending/bc.c
|
||||
[10]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
||||
[11]: http://semver.org/
|
||||
[12]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
|
||||
[13]: https://travis-ci.com/gavinhoward/bc.svg?branch=master
|
||||
[14]: https://travis-ci.com/gavinhoward/bc
|
||||
[15]: https://codecov.io/gh/gavinhoward/bc/branch/master/graph/badge.svg
|
||||
[16]: https://codecov.io/gh/gavinhoward/bc
|
||||
[17]: https://img.shields.io/coverity/scan/16609.svg
|
||||
[18]: https://scan.coverity.com/projects/gavinhoward-bc
|
||||
[19]: ./manuals/benchmarks.md
|
||||
[20]: https://git.yzena.com/gavin/bc
|
||||
[21]: https://gavinhoward.com/2020/04/i-am-moving-away-from-github/
|
||||
[22]: https://www.deepl.com/translator
|
54
RELEASE.md
Normal file
54
RELEASE.md
Normal file
@ -0,0 +1,54 @@
|
||||
# Release Checklist
|
||||
|
||||
This is the checklist for cutting a release.
|
||||
|
||||
1. Update the README.
|
||||
2. Update the manuals.
|
||||
3. Test history manually.
|
||||
4. Test with POSIX test suite.
|
||||
5. Run the randmath.py script an excessive amount and add failing tests to
|
||||
test suite.
|
||||
* debug
|
||||
* release
|
||||
* minrelease
|
||||
6. Fuzz with AFL.
|
||||
* reldebug
|
||||
7. Fix AFL crashes.
|
||||
8. Find ASan crashes on AFL test cases.
|
||||
9. Fix ASan crashes.
|
||||
10. Build with xstatic.
|
||||
11. Run and pass the `release.sh` script on my own machine.
|
||||
12. Run and pass the `release.sh` script, without generated tests and
|
||||
sanitizers, on FreeBSD.
|
||||
13. Run and pass the `release.sh` script, without generated tests, sanitizers,
|
||||
and 64-bit, on Thalheim's ARM server.
|
||||
14. Run and pass the release script, with no generated tests, no clang, no
|
||||
sanitizers, and no valgrind, on NetBSD.
|
||||
15. Run and pass the release script, with no generated tests, no clang, no
|
||||
sanitizers, and no valgrind, on OpenBSD.
|
||||
16. Run Coverity Scan and eliminate warnings, if possible (both only).
|
||||
* debug
|
||||
17. Run `scan-build make`.
|
||||
18. Repeat steps 3-14 again and repeat until nothing is found.
|
||||
19. Update the benchmarks.
|
||||
20. Change the version (remove "-dev") and commit.
|
||||
21. Run `make clean_tests`.
|
||||
22. Run the release script.
|
||||
23. Upload the custom tarball to GitHub.
|
||||
24. Add sha's to release notes.
|
||||
25. Edit release notes for the changelog.
|
||||
26. Increment to the next version (with "-dev").
|
||||
27. Notify the following:
|
||||
* FreeBSD
|
||||
* Adelie Linux
|
||||
* Ataraxia Linux
|
||||
* Sabotage
|
||||
* xstatic
|
||||
* OpenBSD
|
||||
* NetBSD
|
||||
28. Submit new packages for the following:
|
||||
* Alpine Linux
|
||||
* Void Linux
|
||||
* Gentoo Linux
|
||||
* Linux from Scratch
|
||||
* Arch Linux
|
5
TODO.md
Normal file
5
TODO.md
Normal file
@ -0,0 +1,5 @@
|
||||
# TODO
|
||||
|
||||
* Rerun benchmarks.
|
||||
* Redo executable size (with static binaries).
|
||||
* Redo Karatsuba number and update NEWS if necessary.
|
3
codecov.yml
Normal file
3
codecov.yml
Normal file
@ -0,0 +1,3 @@
|
||||
ignore:
|
||||
- "src/history/history.c"
|
||||
- "gen/strgen.c"
|
927
configure.sh
Executable file
927
configure.sh
Executable file
@ -0,0 +1,927 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
script="$0"
|
||||
scriptdir=$(dirname "$script")
|
||||
script=$(basename "$script")
|
||||
|
||||
. "$scriptdir/functions.sh"
|
||||
|
||||
usage() {
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
|
||||
_usage_val=1
|
||||
|
||||
printf "%s\n\n" "$1"
|
||||
|
||||
else
|
||||
_usage_val=0
|
||||
fi
|
||||
|
||||
printf 'usage: %s -h\n' "$script"
|
||||
printf ' %s --help\n' "$script"
|
||||
printf ' %s [-bD|-dB|-c] [-EfgGHMNPT] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\n' "$script"
|
||||
printf ' %s \\\n' "$script"
|
||||
printf ' [--bc-only --disable-dc|--dc-only --disable-bc|--coverage] \\\n'
|
||||
printf ' [--debug --disable-extra-math --disable-generated-tests] \\\n'
|
||||
printf ' [--disable-history --disable-man-pages --disable-nls] \\\n'
|
||||
printf ' [--disable-prompt --disable-strip] \\\n'
|
||||
printf ' [--opt=OPT_LEVEL] [--karatsuba-len=KARATSUBA_LEN] \\\n'
|
||||
printf ' [--prefix=PREFIX] [--bindir=BINDIR] [--datarootdir=DATAROOTDIR] \\\n'
|
||||
printf ' [--datadir=DATADIR] [--mandir=MANDIR] [--man1dir=MAN1DIR] \\\n'
|
||||
printf ' [--force] \\\n'
|
||||
printf '\n'
|
||||
printf ' -b, --bc-only\n'
|
||||
printf ' Build bc only. It is an error if "-d", "--dc-only", "-B", or "--disable-bc"\n'
|
||||
printf ' are specified too.\n'
|
||||
printf ' -B, --disable-bc\n'
|
||||
printf ' Disable bc. It is an error if "-b", "--bc-only", "-D", or "--disable-dc"\n'
|
||||
printf ' are specified too.\n'
|
||||
printf ' -c, --coverage\n'
|
||||
printf ' Generate test coverage code. Requires gcov and regcovr.\n'
|
||||
printf ' It is an error if either "-b" ("-D") or "-d" ("-B") is specified.\n'
|
||||
printf ' Requires a compiler that use gcc-compatible coverage options\n'
|
||||
printf ' -d, --dc-only\n'
|
||||
printf ' Build dc only. It is an error if "-b", "--bc-only", "-D", or "--disable-dc"\n'
|
||||
printf ' are specified too.\n'
|
||||
printf ' -D, --disable-dc\n'
|
||||
printf ' Disable dc. It is an error if "-d", "--dc-only" "-B", or "--disable-bc"\n'
|
||||
printf ' are specified too.\n'
|
||||
printf ' -E, --disable-extra-math\n'
|
||||
printf ' Disable extra math. This includes: "$" operator (truncate to integer),\n'
|
||||
printf ' "@" operator (set number of decimal places), and r(x, p) (rounding\n'
|
||||
printf ' function). Additionally, this option disables the extra printing\n'
|
||||
printf ' functions in the math library.\n'
|
||||
printf ' -f, --force\n'
|
||||
printf ' Force use of all enabled options, even if they do not work. This\n'
|
||||
printf ' option is to allow the maintainer a way to test that certain options\n'
|
||||
printf ' are not failing invisibly. (Development only.)'
|
||||
printf ' -g, --debug\n'
|
||||
printf ' Build in debug mode. Adds the "-g" flag, and if there are no\n'
|
||||
printf ' other CFLAGS, and "-O" was not given, this also adds the "-O0"\n'
|
||||
printf ' flag. If this flag is *not* given, "-DNDEBUG" is added to CPPFLAGS\n'
|
||||
printf ' and a strip flag is added to the link stage.\n'
|
||||
printf ' -G, --disable-generated-tests\n'
|
||||
printf ' Disable generating tests. This is for platforms that do not have a\n'
|
||||
printf ' GNU bc-compatible bc to generate tests.\n'
|
||||
printf ' -h, --help\n'
|
||||
printf ' Print this help message and exit.\n'
|
||||
printf ' -H, --disable-history\n'
|
||||
printf ' Disable history.\n'
|
||||
printf ' -k KARATSUBA_LEN, --karatsuba-len KARATSUBA_LEN\n'
|
||||
printf ' Set the karatsuba length to KARATSUBA_LEN (default is 64).\n'
|
||||
printf ' It is an error if KARATSUBA_LEN is not a number or is less than 16.\n'
|
||||
printf ' -M, --disable-man-pages\n'
|
||||
printf ' Disable installing manpages.\n'
|
||||
printf ' -N, --disable-nls\n'
|
||||
printf ' Disable POSIX locale (NLS) support.\n'
|
||||
printf ' -O OPT_LEVEL, --opt OPT_LEVEL\n'
|
||||
printf ' Set the optimization level. This can also be included in the CFLAGS,\n'
|
||||
printf ' but it is provided, so maintainers can build optimized debug builds.\n'
|
||||
printf ' This is passed through to the compiler, so it must be supported.\n'
|
||||
printf ' -P, --disable-prompt\n'
|
||||
printf ' Disables the prompt in the built bc. The prompt will never show up,\n'
|
||||
printf ' or in other words, it will be permanently disabled and cannot be\n'
|
||||
printf ' enabled.\n'
|
||||
printf ' -T, --disable-strip\n'
|
||||
printf ' Disable stripping symbols from the compiled binary or binaries.\n'
|
||||
printf ' Stripping symbols only happens when debug mode is off.\n'
|
||||
printf ' --prefix PREFIX\n'
|
||||
printf ' The prefix to install to. Overrides "$PREFIX" if it exists.\n'
|
||||
printf ' If PREFIX is "/usr", install path will be "/usr/bin".\n'
|
||||
printf ' Default is "/usr/local".\n'
|
||||
printf ' --bindir BINDIR\n'
|
||||
printf ' The directory to install binaries. Overrides "$BINDIR" if it exists.\n'
|
||||
printf ' Default is "$PREFIX/bin".\n'
|
||||
printf ' --datarootdir DATAROOTDIR\n'
|
||||
printf ' The root location for data files. Overrides "$DATAROOTDIR" if it exists.\n'
|
||||
printf ' Default is "$PREFIX/share".\n'
|
||||
printf ' --datadir DATADIR\n'
|
||||
printf ' The location for data files. Overrides "$DATADIR" if it exists.\n'
|
||||
printf ' Default is "$DATAROOTDIR".\n'
|
||||
printf ' --mandir MANDIR\n'
|
||||
printf ' The location to install manpages to. Overrides "$MANDIR" if it exists.\n'
|
||||
printf ' Default is "$DATADIR/man".\n'
|
||||
printf ' --man1dir MAN1DIR\n'
|
||||
printf ' The location to install Section 1 manpages to. Overrides "$MAN1DIR" if\n'
|
||||
printf ' it exists. Default is "$MANDIR/man1".\n'
|
||||
printf '\n'
|
||||
printf 'In addition, the following environment variables are used:\n'
|
||||
printf '\n'
|
||||
printf ' CC C compiler. Must be compatible with POSIX c99. If there is a\n'
|
||||
printf ' space in the basename of the compiler, the items after the\n'
|
||||
printf ' first space are assumed to be compiler flags, and in that case,\n'
|
||||
printf ' the flags are automatically moved into CFLAGS. Default is\n'
|
||||
printf ' "c99".\n'
|
||||
printf ' HOSTCC Host C compiler. Must be compatible with POSIX c99. If there is\n'
|
||||
printf ' a space in the basename of the compiler, the items after the\n'
|
||||
printf ' first space are assumed to be compiler flags, and in the case,\n'
|
||||
printf ' the flags are automatically moved into HOSTCFLAGS. Default is\n'
|
||||
printf ' "$CC".\n'
|
||||
printf ' HOST_CC Same as HOSTCC. If HOSTCC also exists, it is used.\n'
|
||||
printf ' CFLAGS C compiler flags.\n'
|
||||
printf ' HOSTCFLAGS CFLAGS for HOSTCC. Default is "$CFLAGS".\n'
|
||||
printf ' HOST_CFLAGS Same as HOST_CFLAGS. If HOST_CFLAGS also exists, it is used.\n'
|
||||
printf ' CPPFLAGS C preprocessor flags. Default is "".\n'
|
||||
printf ' LDFLAGS Linker flags. Default is "".\n'
|
||||
printf ' PREFIX The prefix to install to. Default is "/usr/local".\n'
|
||||
printf ' If PREFIX is "/usr", install path will be "/usr/bin".\n'
|
||||
printf ' BINDIR The directory to install binaries. Default is "$PREFIX/bin".\n'
|
||||
printf ' DATAROOTDIR The root location for data files. Default is "$PREFIX/share".\n'
|
||||
printf ' DATADIR The location for data files. Default is "$DATAROOTDIR".\n'
|
||||
printf ' MANDIR The location to install manpages to. Default is "$DATADIR/man".\n'
|
||||
printf ' MAN1DIR The location to install Section 1 manpages to. Default is\n'
|
||||
printf ' "$MANDIR/man1".\n'
|
||||
printf ' NLSPATH The location to install locale catalogs to. Must be an absolute\n'
|
||||
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 ' 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'
|
||||
printf ' interfere with other installed bc executables. Default is "".\n'
|
||||
printf ' DESTDIR For package creation. Default is "". If it is empty when\n'
|
||||
printf ' `%s` is run, it can also be passed to `make install`\n' "$script"
|
||||
printf ' later as an environment variable. If both are specified,\n'
|
||||
printf ' the one given to `%s` takes precedence.\n' "$script"
|
||||
printf ' LONG_BIT The number of bits in a C `long` type. This is mostly for the\n'
|
||||
printf ' embedded space since this `bc` uses `long`s internally for\n'
|
||||
printf ' overflow checking. In C99, a `long` is required to be 32 bits.\n'
|
||||
printf ' For most normal desktop systems, setting this is unnecessary,\n'
|
||||
printf ' except that 32-bit platforms with 64-bit longs may want to set\n'
|
||||
printf ' it to `32`. Default is the default of `LONG_BIT` for the target\n'
|
||||
printf ' platform. Minimum allowed is `32`. It is a build time error if\n'
|
||||
printf ' the specified value of `LONG_BIT` is greater than the default\n'
|
||||
printf ' value of `LONG_BIT` for the target platform.\n'
|
||||
printf ' GEN_HOST Whether to use `gen/strgen.c`, instead of `gen/strgen.sh`, to\n'
|
||||
printf ' produce the C files that contain the help texts as well as the\n'
|
||||
printf ' math libraries. By default, `gen/strgen.c` is used, compiled by\n'
|
||||
printf ' "$HOSTCC" and run on the host machine. Using `gen/strgen.sh`\n'
|
||||
printf ' removes the need to compile and run an executable on the host\n'
|
||||
printf ' machine since `gen/strgen.sh` is a POSIX shell script. However,\n'
|
||||
printf ' `gen/lib2.bc` is perilously close to 4095 characters, the max\n'
|
||||
printf ' supported length of a string literal in C99 (and it could be\n'
|
||||
printf ' added to in the future), and `gen/strgen.sh` generates a string\n'
|
||||
printf ' literal instead of an array, as `gen/strgen.c` does. For most\n'
|
||||
printf ' production-ready compilers, this limit probably is not\n'
|
||||
printf ' enforced, but it could be. Both options are still available for\n'
|
||||
printf ' this reason. If you are sure your compiler does not have the\n'
|
||||
printf ' limit and do not want to compile and run a binary on the host\n'
|
||||
printf ' machine, set this variable to "0". Any other value, or a\n'
|
||||
printf ' non-existent value, will cause the build system to compile and\n'
|
||||
printf ' run `gen/strgen.c`. Default is "".\n'
|
||||
printf ' GEN_EMU Emulator to run string generator code under (leave empty if not\n'
|
||||
printf ' necessary). This is not necessary when using `gen/strgen.sh`.\n'
|
||||
printf ' Default is "".\n'
|
||||
printf '\n'
|
||||
printf 'WARNING: even though `configure.sh` supports both option types, short and\n'
|
||||
printf 'long, it does not support handling both at the same time. Use only one type.\n'
|
||||
|
||||
exit "$_usage_val"
|
||||
}
|
||||
|
||||
replace_ext() {
|
||||
|
||||
if [ "$#" -ne 3 ]; then
|
||||
err_exit "Invalid number of args to $0"
|
||||
fi
|
||||
|
||||
_replace_ext_file="$1"
|
||||
_replace_ext_ext1="$2"
|
||||
_replace_ext_ext2="$3"
|
||||
|
||||
_replace_ext_result=${_replace_ext_file%.$_replace_ext_ext1}.$_replace_ext_ext2
|
||||
|
||||
printf '%s\n' "$_replace_ext_result"
|
||||
}
|
||||
|
||||
replace_exts() {
|
||||
|
||||
if [ "$#" -ne 3 ]; then
|
||||
err_exit "Invalid number of args to $0"
|
||||
fi
|
||||
|
||||
_replace_exts_files="$1"
|
||||
_replace_exts_ext1="$2"
|
||||
_replace_exts_ext2="$3"
|
||||
|
||||
for _replace_exts_file in $_replace_exts_files; do
|
||||
_replace_exts_new_name=$(replace_ext "$_replace_exts_file" "$_replace_exts_ext1" "$_replace_exts_ext2")
|
||||
_replace_exts_result="$_replace_exts_result $_replace_exts_new_name"
|
||||
done
|
||||
|
||||
printf '%s\n' "$_replace_exts_result"
|
||||
}
|
||||
|
||||
replace() {
|
||||
|
||||
if [ "$#" -ne 3 ]; then
|
||||
err_exit "Invalid number of args to $0"
|
||||
fi
|
||||
|
||||
_replace_str="$1"
|
||||
_replace_needle="$2"
|
||||
_replace_replacement="$3"
|
||||
|
||||
substring_replace "$_replace_str" "%%$_replace_needle%%" "$_replace_replacement"
|
||||
}
|
||||
|
||||
gen_file_lists() {
|
||||
|
||||
if [ "$#" -lt 3 ]; then
|
||||
err_exit "Invalid number of args to $0"
|
||||
fi
|
||||
|
||||
_gen_file_lists_contents="$1"
|
||||
shift
|
||||
|
||||
_gen_file_lists_filedir="$1"
|
||||
shift
|
||||
|
||||
_gen_file_lists_typ="$1"
|
||||
shift
|
||||
|
||||
# If there is an extra argument, and it
|
||||
# is zero, we keep the file lists empty.
|
||||
if [ "$#" -gt 0 ]; then
|
||||
_gen_file_lists_use="$1"
|
||||
else
|
||||
_gen_file_lists_use="1"
|
||||
fi
|
||||
|
||||
_gen_file_lists_needle_src="${_gen_file_lists_typ}SRC"
|
||||
_gen_file_lists_needle_obj="${_gen_file_lists_typ}OBJ"
|
||||
_gen_file_lists_needle_gcda="${_gen_file_lists_typ}GCDA"
|
||||
_gen_file_lists_needle_gcno="${_gen_file_lists_typ}GCNO"
|
||||
|
||||
if [ "$_gen_file_lists_use" -ne 0 ]; then
|
||||
|
||||
_gen_file_lists_replacement=$(cd "$_gen_file_lists_filedir" && find . ! -name . -prune -name "*.c" | cut -d/ -f2 | sed "s@^@$_gen_file_lists_filedir/@g" | tr '\n' ' ')
|
||||
_gen_file_lists_contents=$(replace "$_gen_file_lists_contents" "$_gen_file_lists_needle_src" "$_gen_file_lists_replacement")
|
||||
|
||||
_gen_file_lists_replacement=$(replace_exts "$_gen_file_lists_replacement" "c" "o")
|
||||
_gen_file_lists_contents=$(replace "$_gen_file_lists_contents" "$_gen_file_lists_needle_obj" "$_gen_file_lists_replacement")
|
||||
|
||||
_gen_file_lists_replacement=$(replace_exts "$_gen_file_lists_replacement" "o" "gcda")
|
||||
_gen_file_lists_contents=$(replace "$_gen_file_lists_contents" "$_gen_file_lists_needle_gcda" "$_gen_file_lists_replacement")
|
||||
|
||||
_gen_file_lists_replacement=$(replace_exts "$_gen_file_lists_replacement" "gcda" "gcno")
|
||||
_gen_file_lists_contents=$(replace "$_gen_file_lists_contents" "$_gen_file_lists_needle_gcno" "$_gen_file_lists_replacement")
|
||||
|
||||
else
|
||||
_gen_file_lists_contents=$(replace "$_gen_file_lists_contents" "$_gen_file_lists_needle_src" "")
|
||||
_gen_file_lists_contents=$(replace "$_gen_file_lists_contents" "$_gen_file_lists_needle_obj" "")
|
||||
_gen_file_lists_contents=$(replace "$_gen_file_lists_contents" "$_gen_file_lists_needle_gcda" "")
|
||||
_gen_file_lists_contents=$(replace "$_gen_file_lists_contents" "$_gen_file_lists_needle_gcno" "")
|
||||
fi
|
||||
|
||||
printf '%s\n' "$_gen_file_lists_contents"
|
||||
}
|
||||
|
||||
bc_only=0
|
||||
dc_only=0
|
||||
coverage=0
|
||||
karatsuba_len=32
|
||||
debug=0
|
||||
hist=1
|
||||
extra_math=1
|
||||
optimization=""
|
||||
generate_tests=1
|
||||
install_manpages=1
|
||||
nls=1
|
||||
prompt=1
|
||||
force=0
|
||||
strip_bin=1
|
||||
|
||||
while getopts "bBcdDEfgGhHk:MNO:PST-" opt; do
|
||||
|
||||
case "$opt" in
|
||||
b) bc_only=1 ;;
|
||||
B) dc_only=1 ;;
|
||||
c) coverage=1 ;;
|
||||
d) dc_only=1 ;;
|
||||
D) bc_only=1 ;;
|
||||
E) extra_math=0 ;;
|
||||
f) force=1 ;;
|
||||
g) debug=1 ;;
|
||||
G) generate_tests=0 ;;
|
||||
h) usage ;;
|
||||
H) hist=0 ;;
|
||||
k) karatsuba_len="$OPTARG" ;;
|
||||
M) install_manpages=0 ;;
|
||||
N) nls=0 ;;
|
||||
O) optimization="$OPTARG" ;;
|
||||
P) prompt=0 ;;
|
||||
T) strip_bin=0 ;;
|
||||
-)
|
||||
arg="$1"
|
||||
arg="${arg#--}"
|
||||
LONG_OPTARG="${arg#*=}"
|
||||
case $arg in
|
||||
help) usage ;;
|
||||
bc-only) bc_only=1 ;;
|
||||
dc-only) dc_only=1 ;;
|
||||
coverage) coverage=1 ;;
|
||||
debug) debug=1 ;;
|
||||
force) force=1 ;;
|
||||
prefix=?*) PREFIX="$LONG_OPTARG" ;;
|
||||
prefix)
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage "No argument given for '--$arg' option"
|
||||
fi
|
||||
PREFIX="$2"
|
||||
shift ;;
|
||||
bindir=?*) BINDIR="$LONG_OPTARG" ;;
|
||||
bindir)
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage "No argument given for '--$arg' option"
|
||||
fi
|
||||
BINDIR="$2"
|
||||
shift ;;
|
||||
datarootdir=?*) DATAROOTDIR="$LONG_OPTARG" ;;
|
||||
datarootdir)
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage "No argument given for '--$arg' option"
|
||||
fi
|
||||
DATAROOTDIR="$2"
|
||||
shift ;;
|
||||
datadir=?*) DATADIR="$LONG_OPTARG" ;;
|
||||
datadir)
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage "No argument given for '--$arg' option"
|
||||
fi
|
||||
DATADIR="$2"
|
||||
shift ;;
|
||||
mandir=?*) MANDIR="$LONG_OPTARG" ;;
|
||||
mandir)
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage "No argument given for '--$arg' option"
|
||||
fi
|
||||
MANDIR="$2"
|
||||
shift ;;
|
||||
man1dir=?*) MAN1DIR="$LONG_OPTARG" ;;
|
||||
man1dir)
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage "No argument given for '--$arg' option"
|
||||
fi
|
||||
MAN1DIR="$2"
|
||||
shift ;;
|
||||
localedir=?*) LOCALEDIR="$LONG_OPTARG" ;;
|
||||
localedir)
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage "No argument given for '--$arg' option"
|
||||
fi
|
||||
LOCALEDIR="$2"
|
||||
shift ;;
|
||||
karatsuba-len=?*) karatsuba_len="$LONG_OPTARG" ;;
|
||||
karatsuba-len)
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage "No argument given for '--$arg' option"
|
||||
fi
|
||||
karatsuba_len="$1"
|
||||
shift ;;
|
||||
opt=?*) optimization="$LONG_OPTARG" ;;
|
||||
opt)
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage "No argument given for '--$arg' option"
|
||||
fi
|
||||
optimization="$1"
|
||||
shift ;;
|
||||
disable-bc) dc_only=1 ;;
|
||||
disable-dc) bc_only=1 ;;
|
||||
disable-extra-math) extra_math=0 ;;
|
||||
disable-generated-tests) generate_tests=0 ;;
|
||||
disable-history) hist=0 ;;
|
||||
disable-man-pages) install_manpages=0 ;;
|
||||
disable-nls) nls=0 ;;
|
||||
disable-prompt) prompt=0 ;;
|
||||
disable-strip) strip_bin=0 ;;
|
||||
help* | bc-only* | dc-only* | coverage* | debug*)
|
||||
usage "No arg allowed for --$arg option" ;;
|
||||
disable-bc* | disable-dc* | disable-extra-math*)
|
||||
usage "No arg allowed for --$arg option" ;;
|
||||
disable-generated-tests* | disable-history*)
|
||||
usage "No arg allowed for --$arg option" ;;
|
||||
disable-man-pages* | disable-nls* | disable-strip*)
|
||||
usage "No arg allowed for --$arg option" ;;
|
||||
'') break ;; # "--" terminates argument processing
|
||||
* ) usage "Invalid option $LONG_OPTARG" ;;
|
||||
esac
|
||||
shift
|
||||
OPTIND=1 ;;
|
||||
?) usage "Invalid option $opt" ;;
|
||||
esac
|
||||
|
||||
done
|
||||
|
||||
if [ "$bc_only" -eq 1 ] && [ "$dc_only" -eq 1 ]; then
|
||||
usage "Can only specify one of -b(-D) or -d(-B)"
|
||||
fi
|
||||
|
||||
case $karatsuba_len in
|
||||
(*[!0-9]*|'') usage "KARATSUBA_LEN is not a number" ;;
|
||||
(*) ;;
|
||||
esac
|
||||
|
||||
if [ "$karatsuba_len" -lt 16 ]; then
|
||||
usage "KARATSUBA_LEN is less than 16"
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z "${LONG_BIT+set}" ]; then
|
||||
LONG_BIT_DEFINE=""
|
||||
elif [ "$LONG_BIT" -lt 32 ]; then
|
||||
usage "LONG_BIT is less than 32"
|
||||
else
|
||||
LONG_BIT_DEFINE="-DBC_LONG_BIT=\$(BC_LONG_BIT)"
|
||||
fi
|
||||
|
||||
if [ -z "$CC" ]; then
|
||||
CC="c99"
|
||||
else
|
||||
ccbase=$(basename "$CC")
|
||||
suffix=" *"
|
||||
prefix="* "
|
||||
|
||||
if [ "${ccbase%%$suffix}" != "$ccbase" ]; then
|
||||
ccflags="${ccbase#$prefix}"
|
||||
cc="${ccbase%%$suffix}"
|
||||
ccdir=$(dirname "$CC")
|
||||
if [ "$ccdir" = "." ] && [ "${CC#.}" = "$CC" ]; then
|
||||
ccdir=""
|
||||
else
|
||||
ccdir="$ccdir/"
|
||||
fi
|
||||
CC="${ccdir}${cc}"
|
||||
CFLAGS="$CFLAGS $ccflags"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$HOSTCC" ] && [ -z "$HOST_CC" ]; then
|
||||
HOSTCC="$CC"
|
||||
elif [ -z "$HOSTCC" ]; then
|
||||
HOSTCC="$HOST_CC"
|
||||
fi
|
||||
|
||||
if [ "$HOSTCC" != "$CC" ]; then
|
||||
ccbase=$(basename "$HOSTCC")
|
||||
suffix=" *"
|
||||
prefix="* "
|
||||
|
||||
if [ "${ccbase%%$suffix}" != "$ccbase" ]; then
|
||||
ccflags="${ccbase#$prefix}"
|
||||
cc="${ccbase%%$suffix}"
|
||||
ccdir=$(dirname "$HOSTCC")
|
||||
if [ "$ccdir" = "." ] && [ "${HOSTCC#.}" = "$HOSTCC" ]; then
|
||||
ccdir=""
|
||||
else
|
||||
ccdir="$ccdir/"
|
||||
fi
|
||||
HOSTCC="${ccdir}${cc}"
|
||||
HOSTCFLAGS="$HOSTCFLAGS $ccflags"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${HOSTCFLAGS+set}" ] && [ -z "${HOST_CFLAGS+set}" ]; then
|
||||
HOSTCFLAGS="$CFLAGS"
|
||||
elif [ -z "${HOSTCFLAGS+set}" ]; then
|
||||
HOSTCFLAGS="$HOST_CFLAGS"
|
||||
fi
|
||||
|
||||
link="@printf 'No link necessary\\\\n'"
|
||||
main_exec="BC"
|
||||
executable="BC_EXEC"
|
||||
|
||||
bc_test="@tests/all.sh bc $extra_math 1 $generate_tests 0 \$(BC_EXEC)"
|
||||
bc_time_test="@tests/all.sh bc $extra_math 1 $generate_tests 1 \$(BC_EXEC)"
|
||||
|
||||
dc_test="@tests/all.sh dc $extra_math 1 $generate_tests 0 \$(DC_EXEC)"
|
||||
dc_time_test="@tests/all.sh dc $extra_math 1 $generate_tests 1 \$(DC_EXEC)"
|
||||
|
||||
timeconst="@tests/bc/timeconst.sh tests/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.
|
||||
if [ "$debug" -ne 0 ]; then
|
||||
vg_bc_test="@tests/all.sh bc $extra_math 1 $generate_tests 0 valgrind \$(VALGRIND_ARGS) \$(BC_EXEC)"
|
||||
vg_dc_test="@tests/all.sh dc $extra_math 1 $generate_tests 0 valgrind \$(VALGRIND_ARGS) \$(DC_EXEC)"
|
||||
else
|
||||
vg_bc_test="@printf 'Cannot run valgrind without debug flags\\\\n'"
|
||||
vg_dc_test="@printf 'Cannot run valgrind without debug flags\\\\n'"
|
||||
fi
|
||||
|
||||
karatsuba="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
|
||||
karatsuba_test="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'"
|
||||
|
||||
bc_lib="\$(GEN_DIR)/lib.o"
|
||||
bc_help="\$(GEN_DIR)/bc_help.o"
|
||||
dc_help="\$(GEN_DIR)/dc_help.o"
|
||||
|
||||
if [ "$bc_only" -eq 1 ]; then
|
||||
|
||||
bc=1
|
||||
dc=0
|
||||
|
||||
dc_help=""
|
||||
|
||||
executables="bc"
|
||||
|
||||
dc_test="@printf 'No dc tests to run\\\\n'"
|
||||
dc_time_test="@printf 'No dc tests to run\\\\n'"
|
||||
vg_dc_test="@printf 'No dc tests to run\\\\n'"
|
||||
|
||||
install_prereqs=" install_bc_manpage"
|
||||
uninstall_prereqs=" uninstall_bc"
|
||||
uninstall_man_prereqs=" uninstall_bc_manpage"
|
||||
|
||||
elif [ "$dc_only" -eq 1 ]; then
|
||||
|
||||
bc=0
|
||||
dc=1
|
||||
|
||||
bc_lib=""
|
||||
bc_help=""
|
||||
|
||||
executables="dc"
|
||||
|
||||
main_exec="DC"
|
||||
executable="DC_EXEC"
|
||||
|
||||
bc_test="@printf 'No bc tests to run\\\\n'"
|
||||
bc_time_test="@printf 'No bc tests to run\\\\n'"
|
||||
vg_bc_test="@printf 'No bc tests to run\\\\n'"
|
||||
|
||||
timeconst="@printf 'timeconst cannot be run because bc is not built\\\\n'"
|
||||
|
||||
install_prereqs=" install_dc_manpage"
|
||||
uninstall_prereqs=" uninstall_dc"
|
||||
uninstall_man_prereqs=" uninstall_dc_manpage"
|
||||
|
||||
else
|
||||
|
||||
bc=1
|
||||
dc=1
|
||||
|
||||
executables="bc and dc"
|
||||
|
||||
link="\$(LINK) \$(BIN) \$(EXEC_PREFIX)\$(DC)"
|
||||
|
||||
karatsuba="@\$(KARATSUBA) 30 0 \$(BC_EXEC)"
|
||||
karatsuba_test="@\$(KARATSUBA) 1 100 \$(BC_EXEC)"
|
||||
|
||||
install_prereqs=" install_bc_manpage install_dc_manpage"
|
||||
uninstall_prereqs=" uninstall_bc uninstall_dc"
|
||||
uninstall_man_prereqs=" uninstall_bc_manpage uninstall_dc_manpage"
|
||||
|
||||
fi
|
||||
|
||||
if [ "$debug" -eq 1 ]; then
|
||||
|
||||
if [ -z "$CFLAGS" ] && [ -z "$optimization" ]; then
|
||||
CFLAGS="-O0"
|
||||
fi
|
||||
|
||||
CFLAGS="-g $CFLAGS"
|
||||
|
||||
else
|
||||
CPPFLAGS="-DNDEBUG $CPPFLAGS"
|
||||
if [ "$strip_bin" -ne 0 ]; then
|
||||
LDFLAGS="-s $LDFLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$optimization" ]; then
|
||||
CFLAGS="-O$optimization $CFLAGS"
|
||||
fi
|
||||
|
||||
if [ "$coverage" -eq 1 ]; then
|
||||
|
||||
if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then
|
||||
usage "Can only specify -c without -b or -d"
|
||||
fi
|
||||
|
||||
CFLAGS="-fprofile-arcs -ftest-coverage -g -O0 $CFLAGS"
|
||||
CPPFLAGS="-DNDEBUG $CPPFLAGS"
|
||||
|
||||
COVERAGE_OUTPUT="@gcov -pabcdf \$(GCDA) \$(BC_GCDA) \$(DC_GCDA) \$(HISTORY_GCDA) \$(RAND_GCDA)"
|
||||
COVERAGE_OUTPUT="$COVERAGE_OUTPUT;\$(RM) -f \$(GEN)*.gc*"
|
||||
COVERAGE_OUTPUT="$COVERAGE_OUTPUT;gcovr --html-details --output index.html"
|
||||
COVERAGE_PREREQS=" test coverage_output"
|
||||
|
||||
else
|
||||
COVERAGE_OUTPUT="@printf 'Coverage not generated\\\\n'"
|
||||
COVERAGE_PREREQS=""
|
||||
fi
|
||||
|
||||
if [ -z "${DESTDIR+set}" ]; then
|
||||
destdir=""
|
||||
else
|
||||
destdir="DESTDIR = $DESTDIR"
|
||||
fi
|
||||
|
||||
if [ -z "${PREFIX+set}" ]; then
|
||||
PREFIX="/usr/local"
|
||||
fi
|
||||
|
||||
if [ -z "${BINDIR+set}" ]; then
|
||||
BINDIR="$PREFIX/bin"
|
||||
fi
|
||||
|
||||
if [ "$install_manpages" -ne 0 ] || [ "$nls" -ne 0 ]; then
|
||||
if [ -z "${DATAROOTDIR+set}" ]; then
|
||||
DATAROOTDIR="$PREFIX/share"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$install_manpages" -ne 0 ]; then
|
||||
|
||||
if [ -z "${DATADIR+set}" ]; then
|
||||
DATADIR="$DATAROOTDIR"
|
||||
fi
|
||||
|
||||
if [ -z "${MANDIR+set}" ]; then
|
||||
MANDIR="$DATADIR/man"
|
||||
fi
|
||||
|
||||
if [ -z "${MAN1DIR+set}" ]; then
|
||||
MAN1DIR="$MANDIR/man1"
|
||||
fi
|
||||
|
||||
else
|
||||
install_prereqs=""
|
||||
uninstall_man_prereqs=""
|
||||
fi
|
||||
|
||||
if [ "$nls" -ne 0 ]; then
|
||||
|
||||
set +e
|
||||
|
||||
printf 'Testing NLS...\n'
|
||||
|
||||
flags="-DBC_ENABLE_NLS=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
|
||||
flags="$flags -DBC_ENABLE_HISTORY=$hist"
|
||||
flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./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
|
||||
|
||||
err="$?"
|
||||
|
||||
rm -rf "$scriptdir/vm.o"
|
||||
|
||||
# If this errors, it is probably because of building on Windows,
|
||||
# and NLS is not supported on Windows, so disable it.
|
||||
if [ "$err" -ne 0 ]; then
|
||||
printf 'NLS does not work.\n'
|
||||
if [ $force -eq 0 ]; then
|
||||
printf 'Disabling NLS...\n\n'
|
||||
nls=0
|
||||
else
|
||||
printf 'Forcing NLS...\n\n'
|
||||
fi
|
||||
else
|
||||
printf 'NLS works.\n\n'
|
||||
|
||||
printf 'Testing gencat...\n'
|
||||
gencat "$scriptdir/en_US.cat" "$scriptdir/locales/en_US.msg" > /dev/null 2>&1
|
||||
|
||||
err="$?"
|
||||
|
||||
rm -rf "$scriptdir/en_US.cat"
|
||||
|
||||
if [ "$err" -ne 0 ]; then
|
||||
printf 'gencat does not work.\n'
|
||||
if [ $force -eq 0 ]; then
|
||||
printf 'Disabling NLS...\n\n'
|
||||
nls=0
|
||||
else
|
||||
printf 'Forcing NLS...\n\n'
|
||||
fi
|
||||
else
|
||||
|
||||
printf 'gencat works.\n\n'
|
||||
|
||||
if [ "$HOSTCC" != "$CC" ]; then
|
||||
printf 'Cross-compile detected.\n\n'
|
||||
printf 'WARNING: Catalog files generated with gencat may not be portable\n'
|
||||
printf ' across different architectures.\n\n'
|
||||
fi
|
||||
|
||||
if [ -z "$NLSPATH" ]; then
|
||||
NLSPATH="/usr/share/locale/%L/%N"
|
||||
fi
|
||||
|
||||
install_locales_prereqs=" install_locales"
|
||||
uninstall_locales_prereqs=" uninstall_locales"
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
else
|
||||
install_locales_prereqs=""
|
||||
uninstall_locales_prereqs=""
|
||||
fi
|
||||
|
||||
if [ "$hist" -eq 1 ]; then
|
||||
|
||||
set +e
|
||||
|
||||
printf 'Testing history...\n'
|
||||
|
||||
flags="-DBC_ENABLE_HISTORY=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc"
|
||||
flags="$flags -DBC_ENABLE_NLS=$nls"
|
||||
flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/"
|
||||
flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700"
|
||||
|
||||
"$CC" $CPPFLAGS $CFLAGS $flags -c "src/history/history.c" -o "$scriptdir/history.o" > /dev/null 2>&1
|
||||
|
||||
err="$?"
|
||||
|
||||
rm -rf "$scriptdir/history.o"
|
||||
|
||||
# If this errors, it is probably because of building on Windows,
|
||||
# and history is not supported on Windows, so disable it.
|
||||
if [ "$err" -ne 0 ]; then
|
||||
printf 'History does not work.\n'
|
||||
if [ $force -eq 0 ]; then
|
||||
printf 'Disabling history...\n\n'
|
||||
hist=0
|
||||
else
|
||||
printf 'Forcing history...\n\n'
|
||||
fi
|
||||
else
|
||||
printf 'History works.\n\n'
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
fi
|
||||
|
||||
if [ "$extra_math" -eq 1 ] && [ "$bc" -ne 0 ]; then
|
||||
BC_LIB2_O="\$(GEN_DIR)/lib2.o"
|
||||
else
|
||||
BC_LIB2_O=""
|
||||
fi
|
||||
|
||||
GEN="strgen"
|
||||
GEN_EXEC_TARGET="\$(HOSTCC) \$(HOSTCFLAGS) -o \$(GEN_EXEC) \$(GEN_C)"
|
||||
CLEAN_PREREQS=" clean_gen"
|
||||
|
||||
if [ -z "${GEN_HOST+set}" ]; then
|
||||
GEN_HOST=1
|
||||
else
|
||||
if [ "$GEN_HOST" -eq 0 ]; then
|
||||
GEN="strgen.sh"
|
||||
GEN_EXEC_TARGET="@printf 'Do not need to build gen/strgen.c\\\\n'"
|
||||
CLEAN_PREREQS=""
|
||||
fi
|
||||
fi
|
||||
|
||||
# Print out the values; this is for debugging.
|
||||
if [ "$bc" -ne 0 ]; then
|
||||
printf 'Building bc\n'
|
||||
else
|
||||
printf 'Not building bc\n'
|
||||
fi
|
||||
if [ "$dc" -ne 0 ]; then
|
||||
printf 'Building dc\n'
|
||||
else
|
||||
printf 'Not building dc\n'
|
||||
fi
|
||||
printf '\n'
|
||||
printf 'BC_ENABLE_HISTORY=%s\n' "$hist"
|
||||
printf 'BC_ENABLE_EXTRA_MATH=%s\n' "$extra_math"
|
||||
printf 'BC_ENABLE_NLS=%s\n' "$nls"
|
||||
printf 'BC_ENABLE_PROMPT=%s\n' "$prompt"
|
||||
printf '\n'
|
||||
printf 'BC_NUM_KARATSUBA_LEN=%s\n' "$karatsuba_len"
|
||||
printf '\n'
|
||||
printf 'CC=%s\n' "$CC"
|
||||
printf 'CFLAGS=%s\n' "$CFLAGS"
|
||||
printf 'HOSTCC=%s\n' "$HOSTCC"
|
||||
printf 'HOSTCFLAGS=%s\n' "$HOSTCFLAGS"
|
||||
printf 'CPPFLAGS=%s\n' "$CPPFLAGS"
|
||||
printf 'LDFLAGS=%s\n' "$LDFLAGS"
|
||||
printf 'PREFIX=%s\n' "$PREFIX"
|
||||
printf 'BINDIR=%s\n' "$BINDIR"
|
||||
printf 'DATAROOTDIR=%s\n' "$DATAROOTDIR"
|
||||
printf 'DATADIR=%s\n' "$DATADIR"
|
||||
printf 'MANDIR=%s\n' "$MANDIR"
|
||||
printf 'MAN1DIR=%s\n' "$MAN1DIR"
|
||||
printf 'NLSPATH=%s\n' "$NLSPATH"
|
||||
printf 'EXECSUFFIX=%s\n' "$EXECSUFFIX"
|
||||
printf 'EXECPREFIX=%s\n' "$EXECPREFIX"
|
||||
printf 'DESTDIR=%s\n' "$DESTDIR"
|
||||
printf 'LONG_BIT=%s\n' "$LONG_BIT"
|
||||
printf 'GEN_HOST=%s\n' "$GEN_HOST"
|
||||
printf 'GEN_EMU=%s\n' "$GEN_EMU"
|
||||
|
||||
contents=$(cat "$scriptdir/Makefile.in")
|
||||
|
||||
needle="WARNING"
|
||||
replacement='*** WARNING: Autogenerated from Makefile.in. DO NOT MODIFY ***'
|
||||
|
||||
contents=$(replace "$contents" "$needle" "$replacement")
|
||||
|
||||
contents=$(gen_file_lists "$contents" "$scriptdir/src" "")
|
||||
contents=$(gen_file_lists "$contents" "$scriptdir/src/bc" "BC_" "$bc")
|
||||
contents=$(gen_file_lists "$contents" "$scriptdir/src/dc" "DC_" "$dc")
|
||||
contents=$(gen_file_lists "$contents" "$scriptdir/src/history" "HISTORY_" "$hist")
|
||||
contents=$(gen_file_lists "$contents" "$scriptdir/src/rand" "RAND_" "$extra_math")
|
||||
|
||||
contents=$(replace "$contents" "BC_ENABLED" "$bc")
|
||||
contents=$(replace "$contents" "DC_ENABLED" "$dc")
|
||||
contents=$(replace "$contents" "LINK" "$link")
|
||||
|
||||
contents=$(replace "$contents" "HISTORY" "$hist")
|
||||
contents=$(replace "$contents" "EXTRA_MATH" "$extra_math")
|
||||
contents=$(replace "$contents" "NLS" "$nls")
|
||||
contents=$(replace "$contents" "PROMPT" "$prompt")
|
||||
contents=$(replace "$contents" "BC_LIB_O" "$bc_lib")
|
||||
contents=$(replace "$contents" "BC_HELP_O" "$bc_help")
|
||||
contents=$(replace "$contents" "DC_HELP_O" "$dc_help")
|
||||
contents=$(replace "$contents" "BC_LIB2_O" "$BC_LIB2_O")
|
||||
contents=$(replace "$contents" "KARATSUBA_LEN" "$karatsuba_len")
|
||||
|
||||
contents=$(replace "$contents" "NLSPATH" "$NLSPATH")
|
||||
contents=$(replace "$contents" "DESTDIR" "$destdir")
|
||||
contents=$(replace "$contents" "EXECSUFFIX" "$EXECSUFFIX")
|
||||
contents=$(replace "$contents" "EXECPREFIX" "$EXECPREFIX")
|
||||
contents=$(replace "$contents" "BINDIR" "$BINDIR")
|
||||
contents=$(replace "$contents" "MAN1DIR" "$MAN1DIR")
|
||||
contents=$(replace "$contents" "CFLAGS" "$CFLAGS")
|
||||
contents=$(replace "$contents" "HOSTCFLAGS" "$HOSTCFLAGS")
|
||||
contents=$(replace "$contents" "CPPFLAGS" "$CPPFLAGS")
|
||||
contents=$(replace "$contents" "LDFLAGS" "$LDFLAGS")
|
||||
contents=$(replace "$contents" "CC" "$CC")
|
||||
contents=$(replace "$contents" "HOSTCC" "$HOSTCC")
|
||||
contents=$(replace "$contents" "COVERAGE_OUTPUT" "$COVERAGE_OUTPUT")
|
||||
contents=$(replace "$contents" "COVERAGE_PREREQS" "$COVERAGE_PREREQS")
|
||||
contents=$(replace "$contents" "INSTALL_PREREQS" "$install_prereqs")
|
||||
contents=$(replace "$contents" "INSTALL_LOCALES_PREREQS" "$install_locales_prereqs")
|
||||
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" "EXECUTABLES" "$executables")
|
||||
contents=$(replace "$contents" "MAIN_EXEC" "$main_exec")
|
||||
contents=$(replace "$contents" "EXEC" "$executable")
|
||||
|
||||
contents=$(replace "$contents" "BC_TEST" "$bc_test")
|
||||
contents=$(replace "$contents" "BC_TIME_TEST" "$bc_time_test")
|
||||
|
||||
contents=$(replace "$contents" "DC_TEST" "$dc_test")
|
||||
contents=$(replace "$contents" "DC_TIME_TEST" "$dc_time_test")
|
||||
|
||||
contents=$(replace "$contents" "VG_BC_TEST" "$vg_bc_test")
|
||||
contents=$(replace "$contents" "VG_DC_TEST" "$vg_dc_test")
|
||||
|
||||
contents=$(replace "$contents" "TIMECONST" "$timeconst")
|
||||
|
||||
contents=$(replace "$contents" "KARATSUBA" "$karatsuba")
|
||||
contents=$(replace "$contents" "KARATSUBA_TEST" "$karatsuba_test")
|
||||
|
||||
contents=$(replace "$contents" "LONG_BIT" "$LONG_BIT")
|
||||
contents=$(replace "$contents" "LONG_BIT_DEFINE" "$LONG_BIT_DEFINE")
|
||||
|
||||
contents=$(replace "$contents" "GEN" "$GEN")
|
||||
contents=$(replace "$contents" "GEN_EXEC_TARGET" "$GEN_EXEC_TARGET")
|
||||
contents=$(replace "$contents" "CLEAN_PREREQS" "$CLEAN_PREREQS")
|
||||
contents=$(replace "$contents" "GEN_EMU" "$GEN_EMU")
|
||||
|
||||
printf '%s\n' "$contents" > "$scriptdir/Makefile"
|
||||
|
||||
cd "$scriptdir"
|
||||
|
||||
make clean > /dev/null
|
218
functions.sh
Executable file
218
functions.sh
Executable file
@ -0,0 +1,218 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
readlink() {
|
||||
|
||||
_readlink_f="$1"
|
||||
shift
|
||||
|
||||
_readlink_arrow="-> "
|
||||
_readlink_d=$(dirname "$_readlink_f")
|
||||
|
||||
_readlink_lsout=""
|
||||
_readlink_link=""
|
||||
|
||||
_readlink_lsout=$(ls -dl "$_readlink_f")
|
||||
_readlink_link=$(printf '%s' "${_readlink_lsout#*$_readlink_arrow}")
|
||||
|
||||
while [ -z "${_readlink_lsout##*$_readlink_arrow*}" ]; do
|
||||
_readlink_f="$_readlink_d/$_readlink_link"
|
||||
_readlink_d=$(dirname "$_readlink_f")
|
||||
_readlink_lsout=$(ls -dl "$_readlink_f")
|
||||
_readlink_link=$(printf '%s' "${_readlink_lsout#*$_readlink_arrow}")
|
||||
done
|
||||
|
||||
printf '%s' "${_readlink_f##*$_readlink_d/}"
|
||||
}
|
||||
|
||||
err_exit() {
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
printf 'Invalid number of args to err_exit\n'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf '%s\n' "$1"
|
||||
printf '\nexiting...\n'
|
||||
exit "$2"
|
||||
}
|
||||
|
||||
die() {
|
||||
|
||||
_die_d="$1"
|
||||
shift
|
||||
|
||||
_die_msg="$1"
|
||||
shift
|
||||
|
||||
_die_name="$1"
|
||||
shift
|
||||
|
||||
_die_err="$1"
|
||||
shift
|
||||
|
||||
_die_str=$(printf '\n%s %s on test:\n\n %s\n' "$_die_d" "$_die_msg" "$_die_name")
|
||||
|
||||
err_exit "$_die_str" "$_die_err"
|
||||
}
|
||||
|
||||
checkcrash() {
|
||||
|
||||
_checkcrash_d="$1"
|
||||
shift
|
||||
|
||||
_checkcrash_error="$1"
|
||||
shift
|
||||
|
||||
_checkcrash_name="$1"
|
||||
shift
|
||||
|
||||
if [ "$_checkcrash_error" -gt 127 ]; then
|
||||
die "$_checkcrash_d" "crashed ($_checkcrash_error)" \
|
||||
"$_checkcrash_name" "$_checkcrash_error"
|
||||
fi
|
||||
}
|
||||
|
||||
checktest()
|
||||
{
|
||||
_checktest_d="$1"
|
||||
shift
|
||||
|
||||
_checktest_error="$1"
|
||||
shift
|
||||
|
||||
_checktest_name="$1"
|
||||
shift
|
||||
|
||||
_checktest_out="$1"
|
||||
shift
|
||||
|
||||
_checktest_exebase="$1"
|
||||
shift
|
||||
|
||||
checkcrash "$_checktest_d" "$_checktest_error" "$_checktest_name"
|
||||
|
||||
if [ "$_checktest_error" -eq 0 ]; then
|
||||
die "$_checktest_d" "returned no error" "$_checktest_name" 127
|
||||
fi
|
||||
|
||||
if [ "$_checktest_error" -eq 100 ]; then
|
||||
|
||||
_checktest_output=$(cat "$_checktest_out")
|
||||
_checktest_fatal_error="Fatal error"
|
||||
|
||||
if [ "${_checktest_output##*$_checktest_fatal_error*}" ]; then
|
||||
printf "%s\n" "$_checktest_output"
|
||||
die "$_checktest_d" "had memory errors on a non-fatal error" \
|
||||
"$_checktest_name" "$_checktest_error"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -s "$_checktest_out" ]; then
|
||||
die "$_checktest_d" "produced no error message" "$_checktest_name" "$_checktest_error"
|
||||
fi
|
||||
|
||||
# Display the error messages if not directly running exe.
|
||||
# This allows the script to print valgrind output.
|
||||
if [ "$_checktest_exebase" != "bc" -a "$_checktest_exebase" != "dc" ]; then
|
||||
cat "$_checktest_out"
|
||||
fi
|
||||
}
|
||||
|
||||
substring_replace() {
|
||||
|
||||
_substring_replace_str="$1"
|
||||
shift
|
||||
|
||||
_substring_replace_needle="$1"
|
||||
shift
|
||||
|
||||
_substring_replace_replacement="$1"
|
||||
shift
|
||||
|
||||
_substring_replace_result=$(printf '%s\n' "$_substring_replace_str" | \
|
||||
sed -e "s!$_substring_replace_needle!$_substring_replace_replacement!g")
|
||||
|
||||
printf '%s' "$_substring_replace_result"
|
||||
}
|
||||
|
||||
gen_nlspath() {
|
||||
|
||||
_gen_nlspath_nlspath="$1"
|
||||
shift
|
||||
|
||||
_gen_nlspath_locale="$1"
|
||||
shift
|
||||
|
||||
_gen_nlspath_execname="$1"
|
||||
shift
|
||||
|
||||
_gen_nlspath_char="@"
|
||||
_gen_nlspath_modifier="${_gen_nlspath_locale#*$_gen_nlspath_char}"
|
||||
_gen_nlspath_tmplocale="${_gen_nlspath_locale%%$_gen_nlspath_char*}"
|
||||
|
||||
_gen_nlspath_char="."
|
||||
_gen_nlspath_charset="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}"
|
||||
_gen_nlspath_tmplocale="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}"
|
||||
|
||||
if [ "$_gen_nlspath_charset" = "$_gen_nlspath_tmplocale" ]; then
|
||||
_gen_nlspath_charset=""
|
||||
fi
|
||||
|
||||
_gen_nlspath_char="_"
|
||||
_gen_nlspath_territory="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}"
|
||||
_gen_nlspath_language="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}"
|
||||
|
||||
if [ "$_gen_nlspath_territory" = "$_gen_nlspath_tmplocale" ]; then
|
||||
_gen_nlspath_territory=""
|
||||
fi
|
||||
|
||||
if [ "$_gen_nlspath_language" = "$_gen_nlspath_tmplocale" ]; then
|
||||
_gen_nlspath_language=""
|
||||
fi
|
||||
|
||||
_gen_nlspath_needles="%%:%L:%N:%l:%t:%c"
|
||||
|
||||
_gen_nlspath_needles=$(printf '%s' "$_gen_nlspath_needles" | tr ':' '\n')
|
||||
|
||||
for _gen_nlspath_i in $_gen_nlspath_needles; do
|
||||
_gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "$_gen_nlspath_i" "|$_gen_nlspath_i|")
|
||||
done
|
||||
|
||||
_gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%%" "%")
|
||||
_gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%L" "$_gen_nlspath_locale")
|
||||
_gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%N" "$_gen_nlspath_execname")
|
||||
_gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%l" "$_gen_nlspath_language")
|
||||
_gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%t" "$_gen_nlspath_territory")
|
||||
_gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%c" "$_gen_nlspath_charset")
|
||||
|
||||
_gen_nlspath_nlspath=$(printf '%s' "$_gen_nlspath_nlspath" | tr -d '|')
|
||||
|
||||
printf '%s' "$_gen_nlspath_nlspath"
|
||||
}
|
115
gen/bc_help.txt
Normal file
115
gen/bc_help.txt
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* The bc help text.
|
||||
*
|
||||
*/
|
||||
|
||||
usage: %s [options] [file...]
|
||||
|
||||
bc is a command-line, arbitrary-precision calculator with a Turing-complete
|
||||
language. For details, use `man %s`.
|
||||
|
||||
This bc is compatible with both the GNU bc and the POSIX bc spec. See the GNU bc
|
||||
manual (https://www.gnu.org/software/bc/manual/bc.html) and bc spec
|
||||
(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html)
|
||||
for details.
|
||||
|
||||
This bc has three differences to the GNU bc:
|
||||
|
||||
1) Arrays can be passed to the builtin "length" function to get the number of
|
||||
elements currently in the array. The following example prints "1":
|
||||
|
||||
a[0] = 0
|
||||
length(a[])
|
||||
|
||||
2) The precedence of the boolean "not" operator (!) is equal to that of the
|
||||
unary minus (-), or negation, operator. This still allows POSIX-compliant
|
||||
scripts to work while somewhat preserving expected behavior (versus C) and
|
||||
making parsing easier.
|
||||
3) This bc has many more extensions than the GNU bc does. For details, see the
|
||||
man page.
|
||||
|
||||
Options:
|
||||
|
||||
-e expr --expression=expr
|
||||
|
||||
Run "expr" and quit. If multiple expressions or files (see below) are
|
||||
given, they are all run before executing from stdin.
|
||||
|
||||
-f file --file=file
|
||||
|
||||
Run the bc code in "file" and exit. See above as well.
|
||||
|
||||
-g --global-stacks
|
||||
|
||||
Turn scale, ibase, and obase into stacks. This makes the value of each be
|
||||
be restored on returning from functions. See the man page for more
|
||||
details.
|
||||
|
||||
-h --help
|
||||
|
||||
Print this usage message and exit.
|
||||
|
||||
-i --interactive
|
||||
|
||||
Force interactive mode.
|
||||
|
||||
-l --mathlib
|
||||
|
||||
Use predefined math routines:
|
||||
|
||||
s(expr) = sine of expr in radians
|
||||
c(expr) = cosine of expr in radians
|
||||
a(expr) = arctangent of expr, returning radians
|
||||
l(expr) = natural log of expr
|
||||
e(expr) = raises e to the power of expr
|
||||
j(n, x) = Bessel function of integer order n of x
|
||||
|
||||
-P --no-prompt
|
||||
|
||||
Disable the prompt in interactive mode.
|
||||
|
||||
-q --quiet
|
||||
|
||||
Don't print version and copyright.
|
||||
|
||||
-s --standard
|
||||
|
||||
Error if any non-POSIX extensions are used.
|
||||
|
||||
-w --warn
|
||||
|
||||
Warn if any non-POSIX extensions are used.
|
||||
|
||||
-v --version
|
||||
|
||||
Print version information and copyright and exit.
|
101
gen/dc_help.txt
Normal file
101
gen/dc_help.txt
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* The dc help text.
|
||||
*
|
||||
*/
|
||||
|
||||
usage: %s [options] [file...]
|
||||
|
||||
dc is a reverse-polish notation command-line calculator which supports unlimited
|
||||
precision arithmetic. For details, use `man %s`.
|
||||
|
||||
This dc is (mostly) compatible with the FreeBSD dc and the GNU dc. See the
|
||||
FreeBSD man page (https://www.unix.com/man-page/FreeBSD/1/dc/) and the GNU dc
|
||||
manual (https://www.gnu.org/software/bc/manual/dc-1.05/html_mono/dc.html) for
|
||||
details.
|
||||
|
||||
This dc has a few differences from the two above:
|
||||
|
||||
1) When printing a byte stream (command "P"), this bc follows what the FreeBSD
|
||||
dc does.
|
||||
2) This dc implements the GNU extensions for divmod ("~") and modular
|
||||
exponentiation ("|").
|
||||
3) This dc implements all FreeBSD extensions, except for "J" and "M".
|
||||
4) This dc does not implement the run command ("!"), for security reasons.
|
||||
5) Like the FreeBSD dc, this dc supports extended registers. However, they are
|
||||
implemented differently. When it encounters whitespace where a register
|
||||
should be, it skips the whitespace. If the character following is not
|
||||
a lowercase letter, an error is issued. Otherwise, the register name is
|
||||
parsed by the following regex:
|
||||
|
||||
[a-z][a-z0-9_]*
|
||||
|
||||
This generally means that register names will be surrounded by whitespace.
|
||||
|
||||
Examples:
|
||||
|
||||
l idx s temp L index S temp2 < do_thing
|
||||
|
||||
Also note that, unlike the FreeBSD dc, extended registers are not even
|
||||
parsed unless the "-x" option is given. Instead, the space after a command
|
||||
that requires a register name is taken as the register name.
|
||||
|
||||
Options:
|
||||
|
||||
-e expr --expression=expr
|
||||
|
||||
Run "expr" and quit. If multiple expressions or files (see below) are
|
||||
given, they are all run. After running, dc will exit.
|
||||
|
||||
-f file --file=file
|
||||
|
||||
Run the dc code in "file" and exit. See above.
|
||||
|
||||
-h --help
|
||||
|
||||
Print this usage message and exit.
|
||||
|
||||
-i --interactive
|
||||
|
||||
Put dc into interactive mode. See the man page for more details.
|
||||
|
||||
-P --no-prompt
|
||||
|
||||
Disable the prompt in interactive mode.
|
||||
|
||||
-V --version
|
||||
|
||||
Print version and copyright and exit.
|
||||
|
||||
-x --extended-register
|
||||
|
||||
Enable extended register mode.
|
201
gen/lib.bc
Normal file
201
gen/lib.bc
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* The bc math library.
|
||||
*
|
||||
*/
|
||||
|
||||
scale=20
|
||||
define e(x){
|
||||
auto b,s,n,r,d,i,p,f,v
|
||||
b=ibase
|
||||
ibase=A
|
||||
if(x<0){
|
||||
n=1
|
||||
x=-x
|
||||
}
|
||||
s=scale
|
||||
r=6+s+.44*x
|
||||
scale=scale(x)+1
|
||||
while(x>1){
|
||||
d+=1
|
||||
x/=2
|
||||
scale+=1
|
||||
}
|
||||
scale=r
|
||||
r=x+1
|
||||
p=x
|
||||
f=v=1
|
||||
for(i=2;v;++i){
|
||||
p*=x
|
||||
f*=i
|
||||
v=p/f
|
||||
r+=v
|
||||
}
|
||||
while(d--)r*=r
|
||||
scale=s
|
||||
ibase=b
|
||||
if(n)return(1/r)
|
||||
return(r/1)
|
||||
}
|
||||
define l(x){
|
||||
auto b,s,r,p,a,q,i,v
|
||||
if(x<=0)return((1-A^scale)/1)
|
||||
b=ibase
|
||||
ibase=A
|
||||
s=scale
|
||||
scale+=6
|
||||
p=2
|
||||
while(x>=2){
|
||||
p*=2
|
||||
x=sqrt(x)
|
||||
}
|
||||
while(x<=.5){
|
||||
p*=2
|
||||
x=sqrt(x)
|
||||
}
|
||||
r=a=(x-1)/(x+1)
|
||||
q=a*a
|
||||
v=1
|
||||
for(i=3;v;i+=2){
|
||||
a*=q
|
||||
v=a/i
|
||||
r+=v
|
||||
}
|
||||
r*=p
|
||||
scale=s
|
||||
ibase=b
|
||||
return(r/1)
|
||||
}
|
||||
define s(x){
|
||||
auto b,s,r,a,q,i
|
||||
if(x<0)return(-s(-x))
|
||||
b=ibase
|
||||
ibase=A
|
||||
s=scale
|
||||
scale=1.1*s+2
|
||||
a=a(1)
|
||||
scale=0
|
||||
q=(x/a+2)/4
|
||||
x-=4*q*a
|
||||
if(q%2)x=-x
|
||||
scale=s+2
|
||||
r=a=x
|
||||
q=-x*x
|
||||
for(i=3;a;i+=2){
|
||||
a*=q/(i*(i-1))
|
||||
r+=a
|
||||
}
|
||||
scale=s
|
||||
ibase=b
|
||||
return(r/1)
|
||||
}
|
||||
define c(x){
|
||||
auto b,s
|
||||
b=ibase
|
||||
ibase=A
|
||||
s=scale
|
||||
scale*=1.2
|
||||
x=s(2*a(1)+x)
|
||||
scale=s
|
||||
ibase=b
|
||||
return(x/1)
|
||||
}
|
||||
define a(x){
|
||||
auto b,s,r,n,a,m,t,f,i,u
|
||||
b=ibase
|
||||
ibase=A
|
||||
n=1
|
||||
if(x<0){
|
||||
n=-1
|
||||
x=-x
|
||||
}
|
||||
if(scale<65){
|
||||
if(x==1){
|
||||
r=.7853981633974483096156608458198757210492923498437764552437361480/n
|
||||
ibase=b
|
||||
return(r)
|
||||
}
|
||||
if(x==.2){
|
||||
r=.1973955598498807583700497651947902934475851037878521015176889402/n
|
||||
ibase=b
|
||||
return(r)
|
||||
}
|
||||
}
|
||||
s=scale
|
||||
if(x>.2){
|
||||
scale+=5
|
||||
a=a(.2)
|
||||
}
|
||||
scale=s+3
|
||||
while(x>.2){
|
||||
m+=1
|
||||
x=(x-.2)/(1+.2*x)
|
||||
}
|
||||
r=u=x
|
||||
f=-x*x
|
||||
t=1
|
||||
for(i=3;t;i+=2){
|
||||
u*=f
|
||||
t=u/i
|
||||
r+=t
|
||||
}
|
||||
scale=s
|
||||
ibase=b
|
||||
return((m*a+r)/n)
|
||||
}
|
||||
define j(n,x){
|
||||
auto b,s,o,a,i,v,f
|
||||
b=ibase
|
||||
ibase=A
|
||||
s=scale
|
||||
scale=0
|
||||
n/=1
|
||||
if(n<0){
|
||||
n=-n
|
||||
o=n%2
|
||||
}
|
||||
a=1
|
||||
for(i=2;i<=n;++i)a*=i
|
||||
scale=1.5*s
|
||||
a=(x^n)/2^n/a
|
||||
r=v=1
|
||||
f=-x*x/4
|
||||
scale+=length(a)-scale(a)
|
||||
for(i=1;v;++i){
|
||||
v=v*f/i/(n+i)
|
||||
r+=v
|
||||
}
|
||||
scale=s
|
||||
ibase=b
|
||||
if(o)a=-a
|
||||
return(a*r/1)
|
||||
}
|
317
gen/lib2.bc
Normal file
317
gen/lib2.bc
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* The second bc math library.
|
||||
*
|
||||
*/
|
||||
|
||||
define p(x,y){
|
||||
auto a
|
||||
a=y$
|
||||
if(y==a)return (x^a)@scale
|
||||
return e(y*l(x))
|
||||
}
|
||||
define r(x,p){
|
||||
auto t,n
|
||||
if(x==0)return x
|
||||
p=abs(p)$
|
||||
n=(x<0)
|
||||
x=abs(x)
|
||||
t=x@p
|
||||
if(p<scale(x)&&x-t>=5>>p+1)t+=1>>p
|
||||
if(n)t=-t
|
||||
return t
|
||||
}
|
||||
define ceil(x,p){
|
||||
auto t,n
|
||||
if(x==0)return x
|
||||
p=abs(p)$
|
||||
n=(x<0)
|
||||
x=abs(x)
|
||||
t=(x+((x@p<x)>>p))@p
|
||||
if(n)t=-t
|
||||
return t
|
||||
}
|
||||
define f(n){
|
||||
auto r
|
||||
n=abs(n)$
|
||||
for(r=1;n>1;--n)r*=n
|
||||
return r
|
||||
}
|
||||
define perm(n,k){
|
||||
auto f,g,s
|
||||
if(k>n)return 0
|
||||
n=abs(n)$
|
||||
k=abs(k)$
|
||||
f=f(n)
|
||||
g=f(n-k)
|
||||
s=scale
|
||||
scale=0
|
||||
f/=g
|
||||
scale=s
|
||||
return f
|
||||
}
|
||||
define comb(n,r){
|
||||
auto s,f,g,h
|
||||
if(r>n)return 0
|
||||
n=abs(n)$
|
||||
r=abs(r)$
|
||||
s=scale
|
||||
scale=0
|
||||
f=f(n)
|
||||
h=f(r)
|
||||
g=f(n-r)
|
||||
f/=h*g
|
||||
scale=s
|
||||
return f
|
||||
}
|
||||
define log(x,b){
|
||||
auto p,s
|
||||
s=scale
|
||||
if(scale<K)scale=K
|
||||
if(scale(x)>scale)scale=scale(x)
|
||||
scale*=2
|
||||
p=l(x)/l(b)
|
||||
scale=s
|
||||
return p@s
|
||||
}
|
||||
define l2(x){return log(x,2)}
|
||||
define l10(x){return log(x,A)}
|
||||
define root(x,n){
|
||||
auto s,m,r,q,p
|
||||
if(n<0)sqrt(n)
|
||||
n=n$
|
||||
if(n==0)x/n
|
||||
if(n==1)return x
|
||||
if(n==2)return sqrt(x)
|
||||
s=scale
|
||||
scale=0
|
||||
if(x<0&&n%2==0)sqrt(x)
|
||||
scale=s+2
|
||||
m=(x<0)
|
||||
x=abs(x)
|
||||
p=n-1
|
||||
q=10^ceil((length(x$)/n)$,0)
|
||||
while(r!=q){
|
||||
r=q
|
||||
q=(p*r+x/r^p)/n
|
||||
}
|
||||
if(m)r=-r
|
||||
scale=s
|
||||
return r@s
|
||||
}
|
||||
define cbrt(x){return root(x,3)}
|
||||
define pi(s){
|
||||
auto t,v
|
||||
if(s==0)return 3
|
||||
s=abs(s)$
|
||||
t=scale
|
||||
scale=s+1
|
||||
v=4*a(1)
|
||||
scale=t
|
||||
return v@s
|
||||
}
|
||||
define t(x){
|
||||
auto s,c,l
|
||||
l=scale
|
||||
scale+=2
|
||||
s=s(x)
|
||||
c=c(x)
|
||||
scale=l
|
||||
return s/c
|
||||
}
|
||||
define a2(y,x){
|
||||
auto a,p
|
||||
if(!x&&!y)y/x
|
||||
if(x<=0){
|
||||
p=pi(scale+2)
|
||||
if(y<0)p=-p
|
||||
}
|
||||
if(x==0)a=p/2
|
||||
else{
|
||||
scale+=2
|
||||
a=a(y/x)+p
|
||||
scale-=2
|
||||
}
|
||||
return a@scale
|
||||
}
|
||||
define sin(x){return s(x)}
|
||||
define cos(x){return c(x)}
|
||||
define atan(x){return a(x)}
|
||||
define tan(x){return t(x)}
|
||||
define atan2(y,x){return a2(y,x)}
|
||||
define r2d(x){
|
||||
auto r,i,s
|
||||
s=scale
|
||||
scale+=5
|
||||
i=ibase
|
||||
ibase=A
|
||||
r=x*180/pi(scale)
|
||||
ibase=i
|
||||
scale=s
|
||||
return r@s
|
||||
}
|
||||
define d2r(x){
|
||||
auto r,i,s
|
||||
s=scale
|
||||
scale+=5
|
||||
i=ibase
|
||||
ibase=A
|
||||
r=x*pi(scale)/180
|
||||
ibase=i
|
||||
scale=s
|
||||
return r@s
|
||||
}
|
||||
define frand(p){
|
||||
p=abs(p)$
|
||||
return irand(10^p)>>p
|
||||
}
|
||||
define ifrand(i,p){return irand(abs(i)$)+frand(p)}
|
||||
define srand(x){
|
||||
if(irand(2))return -x
|
||||
return x
|
||||
}
|
||||
define brand(){return irand(2)}
|
||||
define void output(x,b){
|
||||
auto c
|
||||
c=obase
|
||||
obase=b
|
||||
x
|
||||
obase=c
|
||||
}
|
||||
define void hex(x){output(x,G)}
|
||||
define void binary(x){output(x,2)}
|
||||
define ubytes(x){
|
||||
auto p,b,i
|
||||
b=ibase
|
||||
ibase=A
|
||||
x=abs(x)$
|
||||
i=2^8
|
||||
for(p=1;i-1<x;p*=2){i*=i}
|
||||
ibase=b
|
||||
return p
|
||||
}
|
||||
define sbytes(x){
|
||||
auto p,b,n,z
|
||||
z=(x<0)
|
||||
x=abs(x)
|
||||
x=x$
|
||||
n=ubytes(x)
|
||||
b=ibase
|
||||
ibase=A
|
||||
p=2^(n*8-1)
|
||||
if(x>p||(!z&&x==p))n*=2
|
||||
ibase=b
|
||||
return n
|
||||
}
|
||||
define void output_byte(x,i){
|
||||
auto j,p,y,b
|
||||
j=ibase
|
||||
ibase=A
|
||||
s=scale
|
||||
scale=0
|
||||
x=abs(x)$
|
||||
b=x/(2^(i*8))
|
||||
b%=2^8
|
||||
y=log(256,obase)
|
||||
if(b>1)p=log(b,obase)+1
|
||||
else p=b
|
||||
for(i=y-p;i>0;--i)print 0
|
||||
if(b)print b
|
||||
scale=s
|
||||
ibase=j
|
||||
}
|
||||
define void output_uint(x,n){
|
||||
auto i,b
|
||||
b=ibase
|
||||
ibase=A
|
||||
for(i=n-1;i>=0;--i){
|
||||
output_byte(x,i)
|
||||
if(i)print" "
|
||||
else print"\n"
|
||||
}
|
||||
ibase=b
|
||||
}
|
||||
define void hex_uint(x,n){
|
||||
auto o
|
||||
o=obase
|
||||
obase=G
|
||||
output_uint(x,n)
|
||||
obase=o
|
||||
}
|
||||
define void binary_uint(x,n){
|
||||
auto o
|
||||
o=obase
|
||||
obase=2
|
||||
output_uint(x,n)
|
||||
obase=o
|
||||
}
|
||||
define void uintn(x,n){
|
||||
if(scale(x)){
|
||||
print"Error: ",x," is not an integer.\n"
|
||||
return
|
||||
}
|
||||
if(x<0){
|
||||
print"Error: ",x," is negative.\n"
|
||||
return
|
||||
}
|
||||
if(x>=2^(n*8)){
|
||||
print"Error: ",x," cannot fit into ",n," unsigned byte(s).\n"
|
||||
return
|
||||
}
|
||||
binary_uint(x,n)
|
||||
hex_uint(x,n)
|
||||
}
|
||||
define void intn(x,n){
|
||||
auto t
|
||||
if(scale(x)){
|
||||
print"Error: ",x," is not an integer.\n"
|
||||
return
|
||||
}
|
||||
t=2^(n*8-1)
|
||||
if(abs(x)>=t&&(x>0||x!=-t)){
|
||||
print "Error: ",x," cannot fit into ",n," signed byte(s).\n"
|
||||
return
|
||||
}
|
||||
if(x<0)x=2^(n*8)-(-x)
|
||||
binary_uint(x,n)
|
||||
hex_uint(x,n)
|
||||
}
|
||||
define void uint8(x){uintn(x,1)}
|
||||
define void int8(x){intn(x,1)}
|
||||
define void uint16(x){uintn(x,2)}
|
||||
define void int16(x){intn(x,2)}
|
||||
define void uint32(x){uintn(x,4)}
|
||||
define void int32(x){intn(x,4)}
|
||||
define void uint64(x){uintn(x,8)}
|
||||
define void int64(x){intn(x,8)}
|
||||
define void uint(x){uintn(x,ubytes(x))}
|
||||
define void int(x){intn(x,sbytes(x))}
|
143
gen/strgen.c
Normal file
143
gen/strgen.c
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Generates a const array from a bc script.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <libgen.h>
|
||||
|
||||
static const char* const bc_gen_header =
|
||||
"// Copyright (c) 2018-2020 Gavin D. Howard and contributors.\n"
|
||||
"// Licensed under the 2-clause BSD license.\n"
|
||||
"// *** AUTOMATICALLY GENERATED FROM %s. DO NOT MODIFY. ***\n";
|
||||
|
||||
static const char* const bc_gen_include = "#include <%s>\n\n";
|
||||
static const char* const bc_gen_label = "const char *%s = \"%s\";\n\n";
|
||||
static const char* const bc_gen_ifdef = "#if %s\n";
|
||||
static const char* const bc_gen_endif = "#endif // %s\n";
|
||||
static const char* const bc_gen_name = "const char %s[] = {\n";
|
||||
|
||||
#define IO_ERR (1)
|
||||
#define INVALID_INPUT_FILE (2)
|
||||
#define INVALID_PARAMS (3)
|
||||
|
||||
#define MAX_WIDTH (74)
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
FILE *in, *out;
|
||||
char *label, *define, *name, *include;
|
||||
int c, count, slashes, err = IO_ERR;
|
||||
bool has_label, has_define, remove_tabs;
|
||||
|
||||
if (argc < 5) {
|
||||
printf("usage: %s input output name header [label [define [remove_tabs]]]\n", argv[0]);
|
||||
return INVALID_PARAMS;
|
||||
}
|
||||
|
||||
name = argv[3];
|
||||
include = argv[4];
|
||||
|
||||
has_label = (argc > 5 && strcmp("", argv[5]) != 0);
|
||||
label = has_label ? argv[5] : "";
|
||||
|
||||
has_define = (argc > 6 && strcmp("", argv[6]) != 0);
|
||||
define = has_define ? argv[6] : "";
|
||||
|
||||
remove_tabs = (argc > 7);
|
||||
|
||||
in = fopen(argv[1], "r");
|
||||
if (!in) return INVALID_INPUT_FILE;
|
||||
|
||||
out = fopen(argv[2], "w");
|
||||
if (!out) goto out_err;
|
||||
|
||||
if (fprintf(out, bc_gen_header, argv[1]) < 0) goto err;
|
||||
if (has_define && fprintf(out, bc_gen_ifdef, define) < 0) goto err;
|
||||
if (fprintf(out, bc_gen_include, include) < 0) goto err;
|
||||
if (has_label && fprintf(out, bc_gen_label, label, argv[1]) < 0) goto err;
|
||||
if (fprintf(out, bc_gen_name, name) < 0) goto err;
|
||||
|
||||
c = count = slashes = 0;
|
||||
|
||||
while (slashes < 2 && (c = fgetc(in)) >= 0) {
|
||||
slashes += (slashes == 1 && c == '/' && fgetc(in) == '\n');
|
||||
slashes += (!slashes && c == '/' && fgetc(in) == '*');
|
||||
}
|
||||
|
||||
if (c < 0) {
|
||||
err = INVALID_INPUT_FILE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
while ((c = fgetc(in)) == '\n');
|
||||
|
||||
while (c >= 0) {
|
||||
|
||||
int val;
|
||||
|
||||
if (!remove_tabs || c != '\t') {
|
||||
|
||||
if (!count && fputc('\t', out) == EOF) goto err;
|
||||
|
||||
val = fprintf(out, "%d,", c);
|
||||
if (val < 0) goto err;
|
||||
|
||||
count += val;
|
||||
|
||||
if (count > MAX_WIDTH) {
|
||||
count = 0;
|
||||
if (fputc('\n', out) == EOF) goto err;
|
||||
}
|
||||
}
|
||||
|
||||
c = fgetc(in);
|
||||
}
|
||||
|
||||
if (!count && (fputc(' ', out) == EOF || fputc(' ', out) == EOF)) goto err;
|
||||
if (fprintf(out, "0\n};\n") < 0) goto err;
|
||||
|
||||
err = (has_define && fprintf(out, bc_gen_endif, define) < 0);
|
||||
|
||||
err:
|
||||
fclose(out);
|
||||
out_err:
|
||||
fclose(in);
|
||||
return err;
|
||||
}
|
79
gen/strgen.sh
Executable file
79
gen/strgen.sh
Executable file
@ -0,0 +1,79 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
export LANG=C
|
||||
export LC_CTYPE=C
|
||||
|
||||
progname=${0##*/}
|
||||
|
||||
if [ $# -lt 4 ]; then
|
||||
echo "usage: $progname input output name header [label [define [remove_tabs]]]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
input="$1"
|
||||
output="$2"
|
||||
name="$3"
|
||||
header="$4"
|
||||
label="$5"
|
||||
define="$6"
|
||||
remove_tabs="$7"
|
||||
|
||||
exec < "$input"
|
||||
exec > "$output"
|
||||
|
||||
if [ -n "$label" ]; then
|
||||
nameline="const char *${label} = \"${input}\";"
|
||||
fi
|
||||
|
||||
if [ -n "$define" ]; then
|
||||
condstart="#if ${define}"
|
||||
condend="#endif"
|
||||
fi
|
||||
|
||||
if [ -n "$remove_tabs" ]; then
|
||||
if [ "$remove_tabs" -ne 0 ]; then
|
||||
remtabsexpr='s: ::g;'
|
||||
fi
|
||||
fi
|
||||
|
||||
cat<<EOF
|
||||
// Licensed under the 2-clause BSD license.
|
||||
// *** AUTOMATICALLY GENERATED FROM ${input}. DO NOT MODIFY. ***
|
||||
|
||||
${condstart}
|
||||
#include <${header}>
|
||||
|
||||
$nameline
|
||||
|
||||
const char ${name}[] =
|
||||
$(sed -e "$remtabsexpr " -e '1,/^$/d; s:\\n:\\\\n:g; s:":\\":g; s:^:":; s:$:\\n":')
|
||||
;
|
||||
${condend}
|
||||
EOF
|
46
include/args.h
Normal file
46
include/args.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for processing command-line arguments.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_ARGS_H
|
||||
#define BC_ARGS_H
|
||||
|
||||
#include <status.h>
|
||||
#include <vm.h>
|
||||
|
||||
void bc_args(int argc, char *argv[]);
|
||||
|
||||
extern const char* const bc_args_env_name;
|
||||
|
||||
#endif // BC_ARGS_H
|
181
include/bc.h
Normal file
181
include/bc.h
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for bc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_BC_H
|
||||
#define BC_BC_H
|
||||
|
||||
#if BC_ENABLED
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <status.h>
|
||||
#include <lex.h>
|
||||
#include <parse.h>
|
||||
|
||||
void bc_main(int argc, char **argv);
|
||||
|
||||
extern const char bc_help[];
|
||||
extern const char bc_lib[];
|
||||
extern const char* bc_lib_name;
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
extern const char bc_lib2[];
|
||||
extern const char* bc_lib2_name;
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
typedef struct BcLexKeyword {
|
||||
uchar data;
|
||||
const char name[9];
|
||||
} BcLexKeyword;
|
||||
|
||||
#define BC_LEX_CHAR_MSB(bit) ((bit) << (CHAR_BIT - 1))
|
||||
|
||||
#define BC_LEX_KW_POSIX(kw) ((kw)->data & (BC_LEX_CHAR_MSB(1)))
|
||||
#define BC_LEX_KW_LEN(kw) ((size_t) ((kw)->data & ~(BC_LEX_CHAR_MSB(1))))
|
||||
|
||||
#define BC_LEX_KW_ENTRY(a, b, c) \
|
||||
{ .data = ((b) & ~(BC_LEX_CHAR_MSB(1))) | BC_LEX_CHAR_MSB(c), .name = a }
|
||||
|
||||
extern const BcLexKeyword bc_lex_kws[];
|
||||
extern const size_t bc_lex_kws_len;
|
||||
|
||||
void bc_lex_token(BcLex *l);
|
||||
|
||||
#define BC_PARSE_TOP_FLAG_PTR(p) ((uint16_t*) bc_vec_top(&(p)->flags))
|
||||
#define BC_PARSE_TOP_FLAG(p) (*(BC_PARSE_TOP_FLAG_PTR(p)))
|
||||
|
||||
#define BC_PARSE_FLAG_BRACE (UINTMAX_C(1)<<0)
|
||||
#define BC_PARSE_BRACE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BRACE)
|
||||
|
||||
#define BC_PARSE_FLAG_FUNC_INNER (UINTMAX_C(1)<<1)
|
||||
#define BC_PARSE_FUNC_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC_INNER)
|
||||
|
||||
#define BC_PARSE_FLAG_FUNC (UINTMAX_C(1)<<2)
|
||||
#define BC_PARSE_FUNC(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_FUNC)
|
||||
|
||||
#define BC_PARSE_FLAG_BODY (UINTMAX_C(1)<<3)
|
||||
#define BC_PARSE_BODY(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_BODY)
|
||||
|
||||
#define BC_PARSE_FLAG_LOOP (UINTMAX_C(1)<<4)
|
||||
#define BC_PARSE_LOOP(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP)
|
||||
|
||||
#define BC_PARSE_FLAG_LOOP_INNER (UINTMAX_C(1)<<5)
|
||||
#define BC_PARSE_LOOP_INNER(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_LOOP_INNER)
|
||||
|
||||
#define BC_PARSE_FLAG_IF (UINTMAX_C(1)<<6)
|
||||
#define BC_PARSE_IF(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF)
|
||||
|
||||
#define BC_PARSE_FLAG_ELSE (UINTMAX_C(1)<<7)
|
||||
#define BC_PARSE_ELSE(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_ELSE)
|
||||
|
||||
#define BC_PARSE_FLAG_IF_END (UINTMAX_C(1)<<8)
|
||||
#define BC_PARSE_IF_END(p) (BC_PARSE_TOP_FLAG(p) & BC_PARSE_FLAG_IF_END)
|
||||
|
||||
#define BC_PARSE_NO_EXEC(p) ((p)->flags.len != 1 || BC_PARSE_TOP_FLAG(p) != 0)
|
||||
|
||||
#define BC_PARSE_DELIMITER(t) \
|
||||
((t) == BC_LEX_SCOLON || (t) == BC_LEX_NLINE || (t) == BC_LEX_EOF)
|
||||
|
||||
#define BC_PARSE_BLOCK_STMT(f) \
|
||||
((f) & (BC_PARSE_FLAG_ELSE | BC_PARSE_FLAG_LOOP_INNER))
|
||||
|
||||
#define BC_PARSE_OP(p, l) (((p) & ~(BC_LEX_CHAR_MSB(1))) | (BC_LEX_CHAR_MSB(l)))
|
||||
|
||||
#define BC_PARSE_OP_DATA(t) bc_parse_ops[((t) - BC_LEX_OP_INC)]
|
||||
#define BC_PARSE_OP_LEFT(op) (BC_PARSE_OP_DATA(op) & BC_LEX_CHAR_MSB(1))
|
||||
#define BC_PARSE_OP_PREC(op) (BC_PARSE_OP_DATA(op) & ~(BC_LEX_CHAR_MSB(1)))
|
||||
|
||||
#define BC_PARSE_EXPR_ENTRY(e1, e2, e3, e4, e5, e6, e7, e8) \
|
||||
((UINTMAX_C(e1) << 7) | (UINTMAX_C(e2) << 6) | (UINTMAX_C(e3) << 5) | \
|
||||
(UINTMAX_C(e4) << 4) | (UINTMAX_C(e5) << 3) | (UINTMAX_C(e6) << 2) | \
|
||||
(UINTMAX_C(e7) << 1) | (UINTMAX_C(e8) << 0))
|
||||
|
||||
#define BC_PARSE_EXPR(i) \
|
||||
(bc_parse_exprs[(((i) & (uchar) ~(0x07)) >> 3)] & (1 << (7 - ((i) & 0x07))))
|
||||
|
||||
#define BC_PARSE_TOP_OP(p) (*((BcLexType*) bc_vec_top(&(p)->ops)))
|
||||
#define BC_PARSE_LEAF(prev, bin_last, rparen) \
|
||||
(!(bin_last) && ((rparen) || bc_parse_inst_isLeaf(prev)))
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
#define BC_PARSE_INST_VAR(t) \
|
||||
((t) >= BC_INST_VAR && (t) <= BC_INST_SEED && (t) != BC_INST_ARRAY)
|
||||
#else // BC_ENABLE_EXTRA_MATH
|
||||
#define BC_PARSE_INST_VAR(t) \
|
||||
((t) >= BC_INST_VAR && (t) <= BC_INST_SCALE && (t) != BC_INST_ARRAY)
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
#define BC_PARSE_PREV_PREFIX(p) \
|
||||
((p) >= BC_INST_NEG && (p) <= BC_INST_BOOL_NOT)
|
||||
#define BC_PARSE_OP_PREFIX(t) ((t) == BC_LEX_OP_BOOL_NOT || (t) == BC_LEX_NEG)
|
||||
|
||||
// We can calculate the conversion between tokens and exprs by subtracting the
|
||||
// position of the first operator in the lex enum and adding the position of
|
||||
// the first in the expr enum. Note: This only works for binary operators.
|
||||
#define BC_PARSE_TOKEN_INST(t) ((uchar) ((t) - BC_LEX_NEG + BC_INST_NEG))
|
||||
|
||||
typedef enum BcParseStatus {
|
||||
|
||||
BC_PARSE_STATUS_SUCCESS,
|
||||
BC_PARSE_STATUS_EMPTY_EXPR,
|
||||
|
||||
} BcParseStatus;
|
||||
|
||||
void bc_parse_expr(BcParse *p, uint8_t flags);
|
||||
|
||||
void bc_parse_parse(BcParse *p);
|
||||
void bc_parse_expr_status(BcParse *p, uint8_t flags, BcParseNext next);
|
||||
|
||||
// This is necessary to clear up for if statements at the end of files.
|
||||
void bc_parse_noElse(BcParse *p);
|
||||
|
||||
extern const char bc_sig_msg[];
|
||||
extern const uchar bc_sig_msg_len;
|
||||
|
||||
extern const char* const bc_parse_const1;
|
||||
extern const uint8_t bc_parse_exprs[];
|
||||
extern const uchar bc_parse_ops[];
|
||||
extern const BcParseNext bc_parse_next_expr;
|
||||
extern const BcParseNext bc_parse_next_param;
|
||||
extern const BcParseNext bc_parse_next_print;
|
||||
extern const BcParseNext bc_parse_next_rel;
|
||||
extern const BcParseNext bc_parse_next_elem;
|
||||
extern const BcParseNext bc_parse_next_for;
|
||||
extern const BcParseNext bc_parse_next_read;
|
||||
|
||||
#endif // BC_ENABLED
|
||||
|
||||
#endif // BC_BC_H
|
70
include/dc.h
Normal file
70
include/dc.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for bc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_DC_H
|
||||
#define BC_DC_H
|
||||
|
||||
#ifndef DC_ENABLE_RAND
|
||||
#define DC_ENABLE_RAND (1)
|
||||
#endif // DC_ENABLE_RAND
|
||||
|
||||
#if DC_ENABLED
|
||||
|
||||
#include <status.h>
|
||||
#include <lex.h>
|
||||
#include <parse.h>
|
||||
|
||||
void dc_main(int argc, char **argv);
|
||||
|
||||
extern const char dc_help[];
|
||||
|
||||
void dc_lex_token(BcLex *l);
|
||||
bool dc_lex_negCommand(BcLex *l);
|
||||
|
||||
extern const char dc_sig_msg[];
|
||||
extern const uchar dc_sig_msg_len;
|
||||
|
||||
extern const uint8_t dc_lex_regs[];
|
||||
extern const size_t dc_lex_regs_len;
|
||||
|
||||
extern const uint8_t dc_lex_tokens[];
|
||||
extern const uint8_t dc_parse_insts[];
|
||||
|
||||
void dc_parse_parse(BcParse *p);
|
||||
void dc_parse_expr(BcParse *p, uint8_t flags);
|
||||
|
||||
#endif // DC_ENABLED
|
||||
|
||||
#endif // BC_DC_H
|
67
include/file.h
Normal file
67
include/file.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for implementing buffered I/O on my own terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_FILE_H
|
||||
#define BC_FILE_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <vector.h>
|
||||
|
||||
#define BC_FILE_ULL_LENGTH (21)
|
||||
|
||||
typedef struct BcFile {
|
||||
|
||||
int fd;
|
||||
char *buf;
|
||||
size_t len;
|
||||
size_t cap;
|
||||
|
||||
} BcFile;
|
||||
|
||||
void bc_file_init(BcFile *f, int fd, char *buf, size_t cap);
|
||||
void bc_file_free(BcFile *f);
|
||||
|
||||
void bc_file_putchar(BcFile *restrict f, uchar c);
|
||||
BcStatus bc_file_flushErr(BcFile *restrict f);
|
||||
void bc_file_flush(BcFile *restrict f);
|
||||
void bc_file_write(BcFile *restrict f, const char *buf, size_t n);
|
||||
void bc_file_printf(BcFile *restrict f, const char *fmt, ...);
|
||||
void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args);
|
||||
void bc_file_puts(BcFile *restrict f, const char *str);
|
||||
|
||||
void bc_file_ultoa(unsigned long long val, char buf[BC_FILE_ULL_LENGTH]);
|
||||
|
||||
#endif // BC_FILE_H
|
260
include/history.h
Normal file
260
include/history.h
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Adapted from the following:
|
||||
*
|
||||
* linenoise.c -- guerrilla line editing library against the idea that a
|
||||
* line editing lib needs to be 20,000 lines of C code.
|
||||
*
|
||||
* You can find the original source code at:
|
||||
* http://github.com/antirez/linenoise
|
||||
*
|
||||
* You can find the fork that this code is based on at:
|
||||
* https://github.com/rain-1/linenoise-mob
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* This code is also under the following license:
|
||||
*
|
||||
* Copyright (c) 2010-2016, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||
* Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for line history.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_HISTORY_H
|
||||
#define BC_HISTORY_H
|
||||
|
||||
#ifndef BC_ENABLE_HISTORY
|
||||
#define BC_ENABLE_HISTORY (1)
|
||||
#endif // BC_ENABLE_HISTORY
|
||||
|
||||
#if BC_ENABLE_HISTORY
|
||||
|
||||
#ifdef _WIN32
|
||||
#error History is not supported on Windows.
|
||||
#endif // _WIN32
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <status.h>
|
||||
#include <vector.h>
|
||||
#include <read.h>
|
||||
|
||||
#if BC_DEBUG_CODE
|
||||
#include <file.h>
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
#define BC_HIST_DEF_COLS (80)
|
||||
#define BC_HIST_MAX_LEN (128)
|
||||
#define BC_HIST_MAX_LINE (4095)
|
||||
#define BC_HIST_SEQ_SIZE (64)
|
||||
|
||||
#define BC_HIST_BUF_LEN(h) ((h)->buf.len - 1)
|
||||
#define BC_HIST_READ(s, n) (bc_history_read((s), (n)) == -1)
|
||||
|
||||
#define BC_HIST_NEXT (false)
|
||||
#define BC_HIST_PREV (true)
|
||||
|
||||
#if BC_DEBUG_CODE
|
||||
|
||||
#define BC_HISTORY_DEBUG_BUF_SIZE (1024)
|
||||
|
||||
#define lndebug(...) \
|
||||
do { \
|
||||
if (bc_history_debug_fp.fd == 0) { \
|
||||
bc_history_debug_buf = bc_vm_malloc(BC_HISTORY_DEBUG_BUF_SIZE); \
|
||||
bc_file_init(&bc_history_debug_fp, \
|
||||
open("/tmp/lndebug.txt", O_APPEND), \
|
||||
BC_HISTORY_DEBUG_BUF_SIZE); \
|
||||
bc_file_printf(&bc_history_debug_fp, \
|
||||
"[%zu %zu %zu] p: %d, rows: %d, " \
|
||||
"rpos: %d, max: %zu, oldmax: %d\n", \
|
||||
l->len, l->pos, l->oldcolpos, plen, rows, rpos, \
|
||||
l->maxrows, old_rows); \
|
||||
} \
|
||||
bc_file_printf(&bc_history_debug_fp, ", " __VA_ARGS__); \
|
||||
bc_file_flush(&bc_history_debug_fp); \
|
||||
} while (0)
|
||||
#else // BC_DEBUG_CODE
|
||||
#define lndebug(fmt, ...)
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
#if !BC_ENABLE_PROMPT
|
||||
#define bc_history_line(h, vec, prompt) bc_history_line(h, vec)
|
||||
#define bc_history_raw(h, prompt) bc_history_raw(h)
|
||||
#define bc_history_edit(h, prompt) bc_history_edit(h)
|
||||
#endif // BC_ENABLE_PROMPT
|
||||
|
||||
typedef enum BcHistoryAction {
|
||||
|
||||
BC_ACTION_NULL = 0,
|
||||
BC_ACTION_CTRL_A = 1,
|
||||
BC_ACTION_CTRL_B = 2,
|
||||
BC_ACTION_CTRL_C = 3,
|
||||
BC_ACTION_CTRL_D = 4,
|
||||
BC_ACTION_CTRL_E = 5,
|
||||
BC_ACTION_CTRL_F = 6,
|
||||
BC_ACTION_CTRL_H = 8,
|
||||
BC_ACTION_TAB = 9,
|
||||
BC_ACTION_LINE_FEED = 10,
|
||||
BC_ACTION_CTRL_K = 11,
|
||||
BC_ACTION_CTRL_L = 12,
|
||||
BC_ACTION_ENTER = 13,
|
||||
BC_ACTION_CTRL_N = 14,
|
||||
BC_ACTION_CTRL_P = 16,
|
||||
BC_ACTION_CTRL_T = 20,
|
||||
BC_ACTION_CTRL_U = 21,
|
||||
BC_ACTION_CTRL_W = 23,
|
||||
BC_ACTION_CTRL_Z = 26,
|
||||
BC_ACTION_ESC = 27,
|
||||
BC_ACTION_BACKSPACE = 127
|
||||
|
||||
} BcHistoryAction;
|
||||
|
||||
/**
|
||||
* This represents the state during line editing. We pass this state
|
||||
* to functions implementing specific editing functionalities.
|
||||
*/
|
||||
typedef struct BcHistory {
|
||||
|
||||
/// Edited line buffer.
|
||||
BcVec buf;
|
||||
|
||||
/// The history.
|
||||
BcVec history;
|
||||
|
||||
#if BC_ENABLE_PROMPT
|
||||
/// Prompt to display.
|
||||
const char *prompt;
|
||||
|
||||
/// Prompt length.
|
||||
size_t plen;
|
||||
#endif // BC_ENABLE_PROMPT
|
||||
|
||||
/// Prompt column length.
|
||||
size_t pcol;
|
||||
|
||||
/// Current cursor position.
|
||||
size_t pos;
|
||||
|
||||
/// Previous refresh cursor column position.
|
||||
size_t oldcolpos;
|
||||
|
||||
/// Number of columns in terminal.
|
||||
size_t cols;
|
||||
|
||||
/// The history index we are currently editing.
|
||||
size_t idx;
|
||||
|
||||
/// The original terminal state.
|
||||
struct termios orig_termios;
|
||||
|
||||
/// These next three are here because pahole found a 4 byte hole here.
|
||||
|
||||
/// This is to signal that there is more, so we don't process yet.
|
||||
bool stdin_has_data;
|
||||
|
||||
/// Whether we are in rawmode.
|
||||
bool rawMode;
|
||||
|
||||
/// Whether the terminal is bad.
|
||||
bool badTerm;
|
||||
|
||||
/// This is to check if stdin has more data.
|
||||
fd_set rdset;
|
||||
|
||||
/// This is to check if stdin has more data.
|
||||
struct timespec ts;
|
||||
|
||||
/// This is to check if stdin has more data.
|
||||
sigset_t sigmask;
|
||||
|
||||
} BcHistory;
|
||||
|
||||
BcStatus bc_history_line(BcHistory *h, BcVec *vec, const char *prompt);
|
||||
|
||||
void bc_history_init(BcHistory *h);
|
||||
void bc_history_free(BcHistory *h);
|
||||
|
||||
extern const char *bc_history_bad_terms[];
|
||||
extern const char bc_history_tab[];
|
||||
extern const size_t bc_history_tab_len;
|
||||
extern const char bc_history_ctrlc[];
|
||||
extern const uint32_t bc_history_wchars[][2];
|
||||
extern const size_t bc_history_wchars_len;
|
||||
extern const uint32_t bc_history_combo_chars[];
|
||||
extern const size_t bc_history_combo_chars_len;
|
||||
#if BC_DEBUG_CODE
|
||||
extern BcFile bc_history_debug_fp;
|
||||
extern char *bc_history_debug_buf;
|
||||
void bc_history_printKeyCodes(BcHistory* l);
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
#endif // BC_ENABLE_HISTORY
|
||||
|
||||
#endif // BC_HISTORY_H
|
326
include/lang.h
Normal file
326
include/lang.h
Normal file
@ -0,0 +1,326 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for program data.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_LANG_H
|
||||
#define BC_LANG_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <status.h>
|
||||
#include <vector.h>
|
||||
#include <num.h>
|
||||
|
||||
#if BC_ENABLED
|
||||
#define BC_INST_IS_ASSIGN(i) \
|
||||
((i) == BC_INST_ASSIGN || (i) == BC_INST_ASSIGN_NO_VAL)
|
||||
#define BC_INST_USE_VAL(i) ((i) <= BC_INST_ASSIGN)
|
||||
#else // BC_ENABLED
|
||||
#define BC_INST_IS_ASSIGN(i) ((i) == BC_INST_ASSIGN_NO_VAL)
|
||||
#define BC_INST_USE_VAL(i) (false)
|
||||
#endif // BC_ENABLED
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define BC_ENABLE_FUNC_FREE (1)
|
||||
#else // NDEBUG
|
||||
#define BC_ENABLE_FUNC_FREE DC_ENABLED
|
||||
#endif // NDEBUG
|
||||
|
||||
typedef enum BcInst {
|
||||
|
||||
#if BC_ENABLED
|
||||
BC_INST_INC = 0,
|
||||
BC_INST_DEC,
|
||||
#endif // BC_ENABLED
|
||||
|
||||
BC_INST_NEG,
|
||||
BC_INST_BOOL_NOT,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_TRUNC,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
BC_INST_POWER,
|
||||
BC_INST_MULTIPLY,
|
||||
BC_INST_DIVIDE,
|
||||
BC_INST_MODULUS,
|
||||
BC_INST_PLUS,
|
||||
BC_INST_MINUS,
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_PLACES,
|
||||
|
||||
BC_INST_LSHIFT,
|
||||
BC_INST_RSHIFT,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
BC_INST_REL_EQ,
|
||||
BC_INST_REL_LE,
|
||||
BC_INST_REL_GE,
|
||||
BC_INST_REL_NE,
|
||||
BC_INST_REL_LT,
|
||||
BC_INST_REL_GT,
|
||||
|
||||
BC_INST_BOOL_OR,
|
||||
BC_INST_BOOL_AND,
|
||||
|
||||
#if BC_ENABLED
|
||||
BC_INST_ASSIGN_POWER,
|
||||
BC_INST_ASSIGN_MULTIPLY,
|
||||
BC_INST_ASSIGN_DIVIDE,
|
||||
BC_INST_ASSIGN_MODULUS,
|
||||
BC_INST_ASSIGN_PLUS,
|
||||
BC_INST_ASSIGN_MINUS,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_ASSIGN_PLACES,
|
||||
BC_INST_ASSIGN_LSHIFT,
|
||||
BC_INST_ASSIGN_RSHIFT,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_ASSIGN,
|
||||
|
||||
BC_INST_ASSIGN_POWER_NO_VAL,
|
||||
BC_INST_ASSIGN_MULTIPLY_NO_VAL,
|
||||
BC_INST_ASSIGN_DIVIDE_NO_VAL,
|
||||
BC_INST_ASSIGN_MODULUS_NO_VAL,
|
||||
BC_INST_ASSIGN_PLUS_NO_VAL,
|
||||
BC_INST_ASSIGN_MINUS_NO_VAL,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_ASSIGN_PLACES_NO_VAL,
|
||||
BC_INST_ASSIGN_LSHIFT_NO_VAL,
|
||||
BC_INST_ASSIGN_RSHIFT_NO_VAL,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
#endif // BC_ENABLED
|
||||
BC_INST_ASSIGN_NO_VAL,
|
||||
|
||||
BC_INST_NUM,
|
||||
BC_INST_VAR,
|
||||
BC_INST_ARRAY_ELEM,
|
||||
#if BC_ENABLED
|
||||
BC_INST_ARRAY,
|
||||
#endif // BC_ENABLED
|
||||
|
||||
BC_INST_ONE,
|
||||
|
||||
#if BC_ENABLED
|
||||
BC_INST_LAST,
|
||||
#endif // BC_ENABLED
|
||||
BC_INST_IBASE,
|
||||
BC_INST_OBASE,
|
||||
BC_INST_SCALE,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_SEED,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_LENGTH,
|
||||
BC_INST_SCALE_FUNC,
|
||||
BC_INST_SQRT,
|
||||
BC_INST_ABS,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_IRAND,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_READ,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_RAND,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_MAXIBASE,
|
||||
BC_INST_MAXOBASE,
|
||||
BC_INST_MAXSCALE,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_INST_MAXRAND,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
BC_INST_PRINT,
|
||||
BC_INST_PRINT_POP,
|
||||
BC_INST_STR,
|
||||
BC_INST_PRINT_STR,
|
||||
|
||||
#if BC_ENABLED
|
||||
BC_INST_JUMP,
|
||||
BC_INST_JUMP_ZERO,
|
||||
|
||||
BC_INST_CALL,
|
||||
|
||||
BC_INST_RET,
|
||||
BC_INST_RET0,
|
||||
BC_INST_RET_VOID,
|
||||
|
||||
BC_INST_HALT,
|
||||
#endif // BC_ENABLED
|
||||
|
||||
BC_INST_POP,
|
||||
|
||||
#if DC_ENABLED
|
||||
BC_INST_POP_EXEC,
|
||||
BC_INST_MODEXP,
|
||||
BC_INST_DIVMOD,
|
||||
|
||||
BC_INST_EXECUTE,
|
||||
BC_INST_EXEC_COND,
|
||||
|
||||
BC_INST_ASCIIFY,
|
||||
BC_INST_PRINT_STREAM,
|
||||
|
||||
BC_INST_PRINT_STACK,
|
||||
BC_INST_CLEAR_STACK,
|
||||
BC_INST_STACK_LEN,
|
||||
BC_INST_DUPLICATE,
|
||||
BC_INST_SWAP,
|
||||
|
||||
BC_INST_LOAD,
|
||||
BC_INST_PUSH_VAR,
|
||||
BC_INST_PUSH_TO_VAR,
|
||||
|
||||
BC_INST_QUIT,
|
||||
BC_INST_NQUIT,
|
||||
#endif // DC_ENABLED
|
||||
|
||||
BC_INST_INVALID = UCHAR_MAX,
|
||||
|
||||
} BcInst;
|
||||
|
||||
typedef struct BcId {
|
||||
char *name;
|
||||
size_t idx;
|
||||
} BcId;
|
||||
|
||||
typedef struct BcLoc {
|
||||
size_t loc;
|
||||
size_t idx;
|
||||
} BcLoc;
|
||||
|
||||
typedef struct BcConst {
|
||||
char *val;
|
||||
BcBigDig base;
|
||||
BcNum num;
|
||||
} BcConst;
|
||||
|
||||
typedef struct BcFunc {
|
||||
|
||||
BcVec code;
|
||||
#if BC_ENABLED
|
||||
BcVec labels;
|
||||
BcVec autos;
|
||||
size_t nparams;
|
||||
#endif // BC_ENABLED
|
||||
|
||||
BcVec strs;
|
||||
BcVec consts;
|
||||
|
||||
const char *name;
|
||||
#if BC_ENABLED
|
||||
bool voidfn;
|
||||
#endif // BC_ENABLED
|
||||
|
||||
} BcFunc;
|
||||
|
||||
typedef enum BcResultType {
|
||||
|
||||
BC_RESULT_VAR,
|
||||
BC_RESULT_ARRAY_ELEM,
|
||||
#if BC_ENABLED
|
||||
BC_RESULT_ARRAY,
|
||||
#endif // BC_ENABLED
|
||||
|
||||
BC_RESULT_STR,
|
||||
|
||||
BC_RESULT_CONSTANT,
|
||||
BC_RESULT_TEMP,
|
||||
|
||||
BC_RESULT_ONE,
|
||||
|
||||
#if BC_ENABLED
|
||||
BC_RESULT_LAST,
|
||||
BC_RESULT_VOID,
|
||||
#endif // BC_ENABLED
|
||||
BC_RESULT_IBASE,
|
||||
BC_RESULT_OBASE,
|
||||
BC_RESULT_SCALE,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_RESULT_SEED,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
} BcResultType;
|
||||
|
||||
typedef union BcResultData {
|
||||
BcNum n;
|
||||
BcVec v;
|
||||
BcLoc loc;
|
||||
} BcResultData;
|
||||
|
||||
typedef struct BcResult {
|
||||
BcResultType t;
|
||||
BcResultData d;
|
||||
} BcResult;
|
||||
|
||||
typedef struct BcInstPtr {
|
||||
size_t func;
|
||||
size_t idx;
|
||||
size_t len;
|
||||
} BcInstPtr;
|
||||
|
||||
typedef enum BcType {
|
||||
BC_TYPE_VAR,
|
||||
BC_TYPE_ARRAY,
|
||||
#if BC_ENABLED
|
||||
BC_TYPE_REF,
|
||||
#endif // BC_ENABLED
|
||||
} BcType;
|
||||
|
||||
struct BcProgram;
|
||||
|
||||
void bc_func_init(BcFunc *f, const char* name);
|
||||
void bc_func_insert(BcFunc *f, struct BcProgram* p, char* name,
|
||||
BcType type, size_t line);
|
||||
void bc_func_reset(BcFunc *f);
|
||||
void bc_func_free(void *func);
|
||||
|
||||
void bc_array_init(BcVec *a, bool nums);
|
||||
void bc_array_copy(BcVec *d, const BcVec *s);
|
||||
|
||||
void bc_string_free(void *string);
|
||||
void bc_const_free(void *constant);
|
||||
void bc_id_free(void *id);
|
||||
void bc_result_clear(BcResult *r);
|
||||
void bc_result_copy(BcResult *d, BcResult *src);
|
||||
void bc_result_free(void *result);
|
||||
|
||||
void bc_array_expand(BcVec *a, size_t len);
|
||||
int bc_id_cmp(const BcId *e1, const BcId *e2);
|
||||
|
||||
#if BC_DEBUG_CODE
|
||||
extern const char* bc_inst_names[];
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
extern const char bc_func_main[];
|
||||
extern const char bc_func_read[];
|
||||
|
||||
#endif // BC_LANG_H
|
232
include/lex.h
Normal file
232
include/lex.h
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for bc's lexer.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_LEX_H
|
||||
#define BC_LEX_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <status.h>
|
||||
#include <vector.h>
|
||||
#include <lang.h>
|
||||
|
||||
#define bc_lex_err(l, e) (bc_vm_error((e), (l)->line))
|
||||
#define bc_lex_verr(l, e, ...) (bc_vm_error((e), (l)->line, __VA_ARGS__))
|
||||
|
||||
#define BC_LEX_NEG_CHAR (BC_IS_BC ? '-' : '_')
|
||||
#define BC_LEX_LAST_NUM_CHAR (BC_IS_BC ? 'Z' : 'F')
|
||||
#define BC_LEX_NUM_CHAR(c, pt, int_only) \
|
||||
(isdigit(c) || ((c) >= 'A' && (c) <= BC_LEX_LAST_NUM_CHAR) || \
|
||||
((c) == '.' && !(pt) && !(int_only)))
|
||||
|
||||
// BC_LEX_NEG is not used in lexing; it is only for parsing.
|
||||
typedef enum BcLexType {
|
||||
|
||||
BC_LEX_EOF,
|
||||
BC_LEX_INVALID,
|
||||
|
||||
#if BC_ENABLED
|
||||
BC_LEX_OP_INC,
|
||||
BC_LEX_OP_DEC,
|
||||
#endif // BC_ENABLED
|
||||
|
||||
BC_LEX_NEG,
|
||||
BC_LEX_OP_BOOL_NOT,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_OP_TRUNC,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
BC_LEX_OP_POWER,
|
||||
BC_LEX_OP_MULTIPLY,
|
||||
BC_LEX_OP_DIVIDE,
|
||||
BC_LEX_OP_MODULUS,
|
||||
BC_LEX_OP_PLUS,
|
||||
BC_LEX_OP_MINUS,
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_OP_PLACES,
|
||||
|
||||
BC_LEX_OP_LSHIFT,
|
||||
BC_LEX_OP_RSHIFT,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
BC_LEX_OP_REL_EQ,
|
||||
BC_LEX_OP_REL_LE,
|
||||
BC_LEX_OP_REL_GE,
|
||||
BC_LEX_OP_REL_NE,
|
||||
BC_LEX_OP_REL_LT,
|
||||
BC_LEX_OP_REL_GT,
|
||||
|
||||
BC_LEX_OP_BOOL_OR,
|
||||
BC_LEX_OP_BOOL_AND,
|
||||
|
||||
#if BC_ENABLED
|
||||
BC_LEX_OP_ASSIGN_POWER,
|
||||
BC_LEX_OP_ASSIGN_MULTIPLY,
|
||||
BC_LEX_OP_ASSIGN_DIVIDE,
|
||||
BC_LEX_OP_ASSIGN_MODULUS,
|
||||
BC_LEX_OP_ASSIGN_PLUS,
|
||||
BC_LEX_OP_ASSIGN_MINUS,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_OP_ASSIGN_PLACES,
|
||||
BC_LEX_OP_ASSIGN_LSHIFT,
|
||||
BC_LEX_OP_ASSIGN_RSHIFT,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
#endif // BC_ENABLED
|
||||
BC_LEX_OP_ASSIGN,
|
||||
|
||||
BC_LEX_NLINE,
|
||||
BC_LEX_WHITESPACE,
|
||||
|
||||
BC_LEX_LPAREN,
|
||||
BC_LEX_RPAREN,
|
||||
|
||||
BC_LEX_LBRACKET,
|
||||
BC_LEX_COMMA,
|
||||
BC_LEX_RBRACKET,
|
||||
|
||||
BC_LEX_LBRACE,
|
||||
BC_LEX_SCOLON,
|
||||
BC_LEX_RBRACE,
|
||||
|
||||
BC_LEX_STR,
|
||||
BC_LEX_NAME,
|
||||
BC_LEX_NUMBER,
|
||||
|
||||
#if BC_ENABLED
|
||||
BC_LEX_KW_AUTO,
|
||||
BC_LEX_KW_BREAK,
|
||||
BC_LEX_KW_CONTINUE,
|
||||
BC_LEX_KW_DEFINE,
|
||||
BC_LEX_KW_FOR,
|
||||
BC_LEX_KW_IF,
|
||||
BC_LEX_KW_LIMITS,
|
||||
BC_LEX_KW_RETURN,
|
||||
BC_LEX_KW_WHILE,
|
||||
BC_LEX_KW_HALT,
|
||||
BC_LEX_KW_LAST,
|
||||
#endif // BC_ENABLED
|
||||
BC_LEX_KW_IBASE,
|
||||
BC_LEX_KW_OBASE,
|
||||
BC_LEX_KW_SCALE,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_KW_SEED,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_KW_LENGTH,
|
||||
BC_LEX_KW_PRINT,
|
||||
BC_LEX_KW_SQRT,
|
||||
BC_LEX_KW_ABS,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_KW_IRAND,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_KW_QUIT,
|
||||
BC_LEX_KW_READ,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_KW_RAND,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_KW_MAXIBASE,
|
||||
BC_LEX_KW_MAXOBASE,
|
||||
BC_LEX_KW_MAXSCALE,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_KW_MAXRAND,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_KW_ELSE,
|
||||
|
||||
#if DC_ENABLED
|
||||
BC_LEX_EQ_NO_REG,
|
||||
BC_LEX_OP_MODEXP,
|
||||
BC_LEX_OP_DIVMOD,
|
||||
|
||||
BC_LEX_COLON,
|
||||
BC_LEX_EXECUTE,
|
||||
BC_LEX_PRINT_STACK,
|
||||
BC_LEX_CLEAR_STACK,
|
||||
BC_LEX_STACK_LEVEL,
|
||||
BC_LEX_DUPLICATE,
|
||||
BC_LEX_SWAP,
|
||||
BC_LEX_POP,
|
||||
|
||||
BC_LEX_ASCIIFY,
|
||||
BC_LEX_PRINT_STREAM,
|
||||
|
||||
BC_LEX_STORE_IBASE,
|
||||
BC_LEX_STORE_OBASE,
|
||||
BC_LEX_STORE_SCALE,
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_STORE_SEED,
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
BC_LEX_LOAD,
|
||||
BC_LEX_LOAD_POP,
|
||||
BC_LEX_STORE_PUSH,
|
||||
BC_LEX_PRINT_POP,
|
||||
BC_LEX_NQUIT,
|
||||
BC_LEX_SCALE_FACTOR,
|
||||
#endif // DC_ENABLED
|
||||
|
||||
} BcLexType;
|
||||
|
||||
struct BcLex;
|
||||
typedef void (*BcLexNext)(struct BcLex*);
|
||||
|
||||
typedef struct BcLex {
|
||||
|
||||
const char *buf;
|
||||
size_t i;
|
||||
size_t line;
|
||||
size_t len;
|
||||
|
||||
BcLexType t;
|
||||
BcLexType last;
|
||||
BcVec str;
|
||||
|
||||
} BcLex;
|
||||
|
||||
void bc_lex_init(BcLex *l);
|
||||
void bc_lex_free(BcLex *l);
|
||||
void bc_lex_file(BcLex *l, const char *file);
|
||||
void bc_lex_text(BcLex *l, const char *text);
|
||||
void bc_lex_next(BcLex *l);
|
||||
|
||||
void bc_lex_lineComment(BcLex *l);
|
||||
void bc_lex_comment(BcLex *l);
|
||||
void bc_lex_whitespace(BcLex *l);
|
||||
void bc_lex_number(BcLex *l, char start);
|
||||
void bc_lex_name(BcLex *l);
|
||||
void bc_lex_commonTokens(BcLex *l, char c);
|
||||
|
||||
void bc_lex_invalidChar(BcLex *l, char c);
|
||||
|
||||
#endif // BC_LEX_H
|
235
include/num.h
Normal file
235
include/num.h
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for the num type.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_NUM_H
|
||||
#define BC_NUM_H
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <status.h>
|
||||
#include <vector.h>
|
||||
|
||||
#ifndef BC_ENABLE_EXTRA_MATH
|
||||
#define BC_ENABLE_EXTRA_MATH (1)
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
#define BC_BASE (10)
|
||||
|
||||
typedef unsigned long ulong;
|
||||
|
||||
// For some reason, LONG_BIT is not defined in some versions of gcc.
|
||||
// I define it here to the minimum accepted value in the POSIX standard.
|
||||
#ifndef LONG_BIT
|
||||
#define LONG_BIT (32)
|
||||
#endif // LONG_BIT
|
||||
|
||||
#ifndef BC_LONG_BIT
|
||||
#define BC_LONG_BIT LONG_BIT
|
||||
#endif // BC_LONG_BIT
|
||||
|
||||
#if BC_LONG_BIT > LONG_BIT
|
||||
#error BC_LONG_BIT cannot be greater than LONG_BIT
|
||||
#endif // BC_LONG_BIT > LONG_BIT
|
||||
|
||||
#if BC_LONG_BIT >= 64
|
||||
|
||||
typedef int_least32_t BcDig;
|
||||
typedef uint64_t BcBigDig;
|
||||
|
||||
#define BC_NUM_BIGDIG_MAX ((BcBigDig) UINT64_MAX)
|
||||
|
||||
#define BC_BASE_DIGS (9)
|
||||
#define BC_BASE_POW (1000000000)
|
||||
|
||||
#define BC_NUM_BIGDIG_C UINT64_C
|
||||
|
||||
#elif BC_LONG_BIT >= 32
|
||||
|
||||
typedef int_least16_t BcDig;
|
||||
typedef uint32_t BcBigDig;
|
||||
|
||||
#define BC_NUM_BIGDIG_MAX ((BcBigDig) UINT32_MAX)
|
||||
|
||||
#define BC_BASE_DIGS (4)
|
||||
#define BC_BASE_POW (10000)
|
||||
|
||||
#define BC_NUM_BIGDIG_C UINT32_C
|
||||
|
||||
#else
|
||||
|
||||
#error BC_LONG_BIT must be at least 32
|
||||
|
||||
#endif // BC_LONG_BIT >= 64
|
||||
|
||||
#define BC_NUM_DEF_SIZE (8)
|
||||
|
||||
typedef struct BcNum {
|
||||
BcDig *restrict num;
|
||||
size_t rdx;
|
||||
size_t scale;
|
||||
size_t len;
|
||||
size_t cap;
|
||||
bool neg;
|
||||
} BcNum;
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
// Forward declaration
|
||||
struct BcRNG;
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
#define BC_NUM_MIN_BASE (BC_NUM_BIGDIG_C(2))
|
||||
#define BC_NUM_MAX_POSIX_IBASE (BC_NUM_BIGDIG_C(16))
|
||||
#define BC_NUM_MAX_IBASE (BC_NUM_BIGDIG_C(36))
|
||||
// This is the max base allowed by bc_num_parseChar().
|
||||
#define BC_NUM_MAX_LBASE (BC_NUM_BIGDIG_C('Z' + BC_BASE + 1))
|
||||
#define BC_NUM_PRINT_WIDTH (BC_NUM_BIGDIG_C(69))
|
||||
|
||||
#ifndef BC_NUM_KARATSUBA_LEN
|
||||
#define BC_NUM_KARATSUBA_LEN (BC_NUM_BIGDIG_C(32))
|
||||
#elif BC_NUM_KARATSUBA_LEN < 16
|
||||
#error BC_NUM_KARATSUBA_LEN must be at least 16.
|
||||
#endif // BC_NUM_KARATSUBA_LEN
|
||||
|
||||
// A crude, but always big enough, calculation of
|
||||
// the size required for ibase and obase BcNum's.
|
||||
#define BC_NUM_BIGDIG_LOG10 (BC_NUM_DEF_SIZE)
|
||||
|
||||
#define BC_NUM_NONZERO(n) ((n)->len)
|
||||
#define BC_NUM_ZERO(n) (!BC_NUM_NONZERO(n))
|
||||
#define BC_NUM_ONE(n) ((n)->len == 1 && (n)->rdx == 0 && (n)->num[0] == 1)
|
||||
|
||||
#define BC_NUM_NUM_LETTER(c) ((c) - 'A' + BC_BASE)
|
||||
|
||||
#define BC_NUM_KARATSUBA_ALLOCS (6)
|
||||
|
||||
#define BC_NUM_ROUND_POW(s) (bc_vm_growSize((s), BC_BASE_DIGS - 1))
|
||||
#define BC_NUM_RDX(s) (BC_NUM_ROUND_POW(s) / BC_BASE_DIGS)
|
||||
|
||||
#define BC_NUM_SIZE(n) ((n) * sizeof(BcDig))
|
||||
|
||||
#if BC_DEBUG_CODE
|
||||
#define BC_NUM_PRINT(x) fprintf(stderr, "%s = %lu\n", #x, (unsigned long)(x))
|
||||
#define DUMP_NUM bc_num_dump
|
||||
#else // BC_DEBUG_CODE
|
||||
#undef DUMP_NUM
|
||||
#define DUMP_NUM(x,y)
|
||||
#define BC_NUM_PRINT(x)
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
typedef void (*BcNumBinaryOp)(BcNum*, BcNum*, BcNum*, size_t);
|
||||
typedef size_t (*BcNumBinaryOpReq)(const BcNum*, const BcNum*, size_t);
|
||||
typedef void (*BcNumDigitOp)(size_t, size_t, bool);
|
||||
typedef void (*BcNumShiftAddOp)(BcDig*, const BcDig*, size_t);
|
||||
|
||||
void bc_num_init(BcNum *restrict n, size_t req);
|
||||
void bc_num_setup(BcNum *restrict n, BcDig *restrict num, size_t cap);
|
||||
void bc_num_copy(BcNum *d, const BcNum *s);
|
||||
void bc_num_createCopy(BcNum *d, const BcNum *s);
|
||||
void bc_num_createFromBigdig(BcNum *n, BcBigDig val);
|
||||
void bc_num_clear(BcNum *restrict n);
|
||||
void bc_num_free(void *num);
|
||||
|
||||
size_t bc_num_scale(const BcNum *restrict n);
|
||||
size_t bc_num_len(const BcNum *restrict n);
|
||||
|
||||
void bc_num_bigdig(const BcNum *restrict n, BcBigDig *result);
|
||||
void bc_num_bigdig2(const BcNum *restrict n, BcBigDig *result);
|
||||
void bc_num_bigdig2num(BcNum *restrict n, BcBigDig val);
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
void bc_num_irand(const BcNum *restrict a, BcNum *restrict b,
|
||||
struct BcRNG *restrict rng);
|
||||
void bc_num_rng(const BcNum *restrict n, struct BcRNG *rng);
|
||||
void bc_num_createFromRNG(BcNum *restrict n, struct BcRNG *rng);
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
void bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale);
|
||||
void bc_num_sub(BcNum *a, BcNum *b, BcNum *c, size_t scale);
|
||||
void bc_num_mul(BcNum *a, BcNum *b, BcNum *c, size_t scale);
|
||||
void bc_num_div(BcNum *a, BcNum *b, BcNum *c, size_t scale);
|
||||
void bc_num_mod(BcNum *a, BcNum *b, BcNum *c, size_t scale);
|
||||
void bc_num_pow(BcNum *a, BcNum *b, BcNum *c, size_t scale);
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
void bc_num_places(BcNum *a, BcNum *b, BcNum *c, size_t scale);
|
||||
void bc_num_lshift(BcNum *a, BcNum *b, BcNum *c, size_t scale);
|
||||
void bc_num_rshift(BcNum *a, BcNum *b, BcNum *c, size_t scale);
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
void bc_num_sqrt(BcNum *restrict a, BcNum *restrict b, size_t scale);
|
||||
void bc_num_divmod(BcNum *a, BcNum *b, BcNum *c, BcNum *d, size_t scale);
|
||||
|
||||
size_t bc_num_addReq(const BcNum* a, const BcNum* b, size_t scale);
|
||||
|
||||
size_t bc_num_mulReq(const BcNum *a, const BcNum *b, size_t scale);
|
||||
size_t bc_num_powReq(const BcNum *a, const BcNum *b, size_t scale);
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
size_t bc_num_placesReq(const BcNum *a, const BcNum *b, size_t scale);
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
void bc_num_truncate(BcNum *restrict n, size_t places);
|
||||
ssize_t bc_num_cmp(const BcNum *a, const BcNum *b);
|
||||
|
||||
#if DC_ENABLED
|
||||
void bc_num_modexp(BcNum *a, BcNum *b, BcNum *c, BcNum *restrict d);
|
||||
#endif // DC_ENABLED
|
||||
|
||||
void bc_num_one(BcNum *restrict n);
|
||||
ssize_t bc_num_cmpZero(const BcNum *n);
|
||||
|
||||
void bc_num_parse(BcNum *restrict n, const char *restrict val,
|
||||
BcBigDig base, bool letter);
|
||||
void bc_num_print(BcNum *restrict n, BcBigDig base, bool newline);
|
||||
#if DC_ENABLED
|
||||
void bc_num_stream(BcNum *restrict n, BcBigDig base);
|
||||
#endif // DC_ENABLED
|
||||
|
||||
#if BC_DEBUG_CODE
|
||||
void bc_num_printDebug(const BcNum *n, const char *name, bool emptyline);
|
||||
void bc_num_printDigs(const BcDig* n, size_t len, bool emptyline);
|
||||
void bc_num_printWithDigs(const BcNum *n, const char *name, bool emptyline);
|
||||
void bc_num_dump(const char *varname, const BcNum *n);
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
extern const char bc_num_hex_digits[];
|
||||
extern const BcBigDig bc_num_pow10[BC_BASE_DIGS + 1];
|
||||
|
||||
extern const BcDig bc_num_bigdigMax[];
|
||||
extern const size_t bc_num_bigdigMax_size;
|
||||
|
||||
#endif // BC_NUM_H
|
79
include/opt.h
Normal file
79
include/opt.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Adapted from https://github.com/skeeto/optparse
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for getopt_long() replacement.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_OPT_H
|
||||
#define BC_OPT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct BcOpt {
|
||||
char **argv;
|
||||
size_t optind;
|
||||
int optopt;
|
||||
int subopt;
|
||||
char *optarg;
|
||||
} BcOpt;
|
||||
|
||||
typedef enum BcOptType {
|
||||
BC_OPT_NONE,
|
||||
BC_OPT_REQUIRED,
|
||||
BC_OPT_BC_ONLY,
|
||||
BC_OPT_DC_ONLY,
|
||||
} BcOptType;
|
||||
|
||||
typedef struct BcOptLong {
|
||||
const char *name;
|
||||
BcOptType type;
|
||||
int val;
|
||||
} BcOptLong;
|
||||
|
||||
void bc_opt_init(BcOpt *o, char **argv);
|
||||
|
||||
int bc_opt_parse(BcOpt *o, const BcOptLong *longopts);
|
||||
|
||||
#define BC_OPT_ISDASHDASH(a) \
|
||||
((a) != NULL && (a)[0] == '-' && (a)[1] == '-' && (a)[2] == '\0')
|
||||
|
||||
#define BC_OPT_ISSHORTOPT(a) \
|
||||
((a) != NULL && (a)[0] == '-' && (a)[1] != '-' && (a)[1] != '\0')
|
||||
|
||||
#define BC_OPT_ISLONGOPT(a) \
|
||||
((a) != NULL && (a)[0] == '-' && (a)[1] == '-' && (a)[2] != '\0')
|
||||
|
||||
#endif // BC_OPT_H
|
115
include/parse.h
Normal file
115
include/parse.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for bc's parser.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_PARSE_H
|
||||
#define BC_PARSE_H
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <status.h>
|
||||
#include <vector.h>
|
||||
#include <lex.h>
|
||||
#include <lang.h>
|
||||
|
||||
#define BC_PARSE_REL (UINTMAX_C(1)<<0)
|
||||
#define BC_PARSE_PRINT (UINTMAX_C(1)<<1)
|
||||
#define BC_PARSE_NOCALL (UINTMAX_C(1)<<2)
|
||||
#define BC_PARSE_NOREAD (UINTMAX_C(1)<<3)
|
||||
#define BC_PARSE_ARRAY (UINTMAX_C(1)<<4)
|
||||
#define BC_PARSE_NEEDVAL (UINTMAX_C(1)<<5)
|
||||
|
||||
#if BC_ENABLED
|
||||
#define BC_PARSE_CAN_PARSE(p) \
|
||||
((p).l.t != BC_LEX_EOF && (p).l.t != BC_LEX_KW_DEFINE)
|
||||
#else // BC_ENABLED
|
||||
#define BC_PARSE_CAN_PARSE(p) ((p).l.t != BC_LEX_EOF)
|
||||
#endif // BC_ENABLED
|
||||
|
||||
#define bc_parse_push(p, i) (bc_vec_pushByte(&(p)->func->code, (uchar) (i)))
|
||||
#define bc_parse_pushIndex(p, idx) (bc_vec_pushIndex(&(p)->func->code, (idx)))
|
||||
|
||||
#define bc_parse_err(p, e) (bc_vm_error((e), (p)->l.line))
|
||||
#define bc_parse_verr(p, e, ...) (bc_vm_error((e), (p)->l.line, __VA_ARGS__))
|
||||
|
||||
typedef struct BcParseNext {
|
||||
uchar len;
|
||||
uchar tokens[4];
|
||||
} BcParseNext;
|
||||
|
||||
#define BC_PARSE_NEXT_TOKENS(...) .tokens = { __VA_ARGS__ }
|
||||
#define BC_PARSE_NEXT(a, ...) \
|
||||
{ .len = (uchar) (a), BC_PARSE_NEXT_TOKENS(__VA_ARGS__) }
|
||||
|
||||
struct BcParse;
|
||||
struct BcProgram;
|
||||
|
||||
typedef void (*BcParseParse)(struct BcParse*);
|
||||
typedef void (*BcParseExpr)(struct BcParse*, uint8_t);
|
||||
|
||||
typedef struct BcParse {
|
||||
|
||||
BcLex l;
|
||||
|
||||
#if BC_ENABLED
|
||||
BcVec flags;
|
||||
BcVec exits;
|
||||
BcVec conds;
|
||||
BcVec ops;
|
||||
BcVec buf;
|
||||
#endif // BC_ENABLED
|
||||
|
||||
struct BcProgram *prog;
|
||||
BcFunc *func;
|
||||
size_t fidx;
|
||||
|
||||
bool auto_part;
|
||||
|
||||
} BcParse;
|
||||
|
||||
void bc_parse_init(BcParse *p, struct BcProgram *prog, size_t func);
|
||||
void bc_parse_free(BcParse *p);
|
||||
void bc_parse_reset(BcParse *p);
|
||||
|
||||
void bc_parse_addString(BcParse *p);
|
||||
void bc_parse_number(BcParse *p);
|
||||
void bc_parse_updateFunc(BcParse *p, size_t fidx);
|
||||
void bc_parse_pushName(const BcParse* p, char *name, bool var);
|
||||
void bc_parse_text(BcParse *p, const char *text);
|
||||
|
||||
extern const char bc_parse_one[];
|
||||
|
||||
#endif // BC_PARSE_H
|
183
include/program.h
Normal file
183
include/program.h
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for bc programs.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_PROGRAM_H
|
||||
#define BC_PROGRAM_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <status.h>
|
||||
#include <parse.h>
|
||||
#include <lang.h>
|
||||
#include <num.h>
|
||||
#include <rand.h>
|
||||
|
||||
#define BC_PROG_GLOBALS_IBASE (0)
|
||||
#define BC_PROG_GLOBALS_OBASE (1)
|
||||
#define BC_PROG_GLOBALS_SCALE (2)
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
#define BC_PROG_MAX_RAND (3)
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
#define BC_PROG_GLOBALS_LEN (3 + BC_ENABLE_EXTRA_MATH)
|
||||
|
||||
#define BC_PROG_ONE_CAP (1)
|
||||
|
||||
typedef struct BcProgram {
|
||||
|
||||
BcBigDig globals[BC_PROG_GLOBALS_LEN];
|
||||
BcVec globals_v[BC_PROG_GLOBALS_LEN];
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
BcRNG rng;
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
BcVec results;
|
||||
BcVec stack;
|
||||
|
||||
BcVec *consts;
|
||||
BcVec *strs;
|
||||
|
||||
BcVec fns;
|
||||
BcVec fn_map;
|
||||
|
||||
BcVec vars;
|
||||
BcVec var_map;
|
||||
|
||||
BcVec arrs;
|
||||
BcVec arr_map;
|
||||
|
||||
#if DC_ENABLED
|
||||
BcVec tail_calls;
|
||||
|
||||
BcBigDig strm;
|
||||
BcNum strmb;
|
||||
#endif // DC_ENABLED
|
||||
|
||||
BcNum one;
|
||||
|
||||
#if BC_ENABLED
|
||||
BcNum last;
|
||||
#endif // BC_ENABLED
|
||||
|
||||
#if DC_ENABLED
|
||||
// This uses BC_NUM_LONG_LOG10 because it is used in bc_num_ulong2num(),
|
||||
// which attempts to realloc, unless it is big enough. This is big enough.
|
||||
BcDig strmb_num[BC_NUM_BIGDIG_LOG10];
|
||||
#endif // DC_ENABLED
|
||||
|
||||
BcDig one_num[BC_PROG_ONE_CAP];
|
||||
|
||||
} BcProgram;
|
||||
|
||||
#define BC_PROG_STACK(s, n) ((s)->len >= ((size_t) (n)))
|
||||
|
||||
#define BC_PROG_GLOBAL_PTR(v) (bc_vec_top(v))
|
||||
#define BC_PROG_GLOBAL(v) (*((BcBigDig*) BC_PROG_GLOBAL_PTR(v)))
|
||||
|
||||
#define BC_PROG_IBASE(p) ((p)->globals[BC_PROG_GLOBALS_IBASE])
|
||||
#define BC_PROG_OBASE(p) ((p)->globals[BC_PROG_GLOBALS_OBASE])
|
||||
#define BC_PROG_SCALE(p) ((p)->globals[BC_PROG_GLOBALS_SCALE])
|
||||
|
||||
#define BC_PROG_MAIN (0)
|
||||
#define BC_PROG_READ (1)
|
||||
|
||||
#define bc_program_retire(p, nres, nops) \
|
||||
(bc_vec_npopAt(&(p)->results, (nops), (p)->results.len - (nres + nops)))
|
||||
|
||||
#if DC_ENABLED
|
||||
#define BC_PROG_REQ_FUNCS (2)
|
||||
#if !BC_ENABLED
|
||||
// For dc only, last is always true.
|
||||
#define bc_program_copyToVar(p, name, t, last) \
|
||||
bc_program_copyToVar(p, name, t)
|
||||
#endif // !BC_ENABLED
|
||||
#else // DC_ENABLED
|
||||
// For bc, 'pop' and 'copy' are always false.
|
||||
#define bc_program_pushVar(p, code, bgn, pop, copy) \
|
||||
bc_program_pushVar(p, code, bgn)
|
||||
#ifdef NDEBUG
|
||||
#define BC_PROG_NO_STACK_CHECK
|
||||
#endif // NDEBUG
|
||||
#endif // DC_ENABLED
|
||||
|
||||
#define BC_PROG_STR(n) ((n)->num == NULL && !(n)->cap)
|
||||
#if BC_ENABLED
|
||||
#define BC_PROG_NUM(r, n) \
|
||||
((r)->t != BC_RESULT_ARRAY && (r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
|
||||
#else // BC_ENABLED
|
||||
#define BC_PROG_NUM(r, n) ((r)->t != BC_RESULT_STR && !BC_PROG_STR(n))
|
||||
// For dc, inst is always BC_INST_ARRAY_ELEM.
|
||||
#define bc_program_pushArray(p, code, bgn, inst) \
|
||||
bc_program_pushArray(p, code, bgn)
|
||||
#endif // BC_ENABLED
|
||||
|
||||
typedef void (*BcProgramUnary)(BcResult*, BcNum*);
|
||||
|
||||
void bc_program_init(BcProgram *p);
|
||||
void bc_program_free(BcProgram *p);
|
||||
|
||||
#if BC_DEBUG_CODE
|
||||
#if BC_ENABLED && DC_ENABLED
|
||||
void bc_program_code(const BcProgram *p);
|
||||
void bc_program_printInst(const BcProgram *p, const char *code,
|
||||
size_t *restrict bgn);
|
||||
void bc_program_printStackDebug(BcProgram* p);
|
||||
#endif // BC_ENABLED && DC_ENABLED
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
size_t bc_program_search(BcProgram *p, const char* id, bool var);
|
||||
size_t bc_program_insertFunc(BcProgram *p, const char *name);
|
||||
void bc_program_reset(BcProgram *p);
|
||||
void bc_program_exec(BcProgram *p);
|
||||
|
||||
void bc_program_negate(BcResult *r, BcNum *n);
|
||||
void bc_program_not(BcResult *r, BcNum *n);
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
void bc_program_trunc(BcResult *r, BcNum *n);
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
extern const BcNumBinaryOp bc_program_ops[];
|
||||
extern const BcNumBinaryOpReq bc_program_opReqs[];
|
||||
extern const BcProgramUnary bc_program_unarys[];
|
||||
extern const char bc_program_exprs_name[];
|
||||
extern const char bc_program_stdin_name[];
|
||||
extern const char bc_program_ready_msg[];
|
||||
extern const size_t bc_program_ready_msg_len;
|
||||
extern const char bc_program_esc_chars[];
|
||||
extern const char bc_program_esc_seqs[];
|
||||
|
||||
#endif // BC_PROGRAM_H
|
229
include/rand.h
Normal file
229
include/rand.h
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2019 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Parts of this code are adapted from the following:
|
||||
*
|
||||
* PCG, A Family of Better Random Number Generators.
|
||||
*
|
||||
* You can find the original source code at:
|
||||
* https://github.com/imneme/pcg-c
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Parts of this code are also under the following license:
|
||||
*
|
||||
* Copyright (c) 2014-2017 Melissa O'Neill and PCG Project contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for the RNG.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_RAND_H
|
||||
#define BC_RAND_H
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <vector.h>
|
||||
#include <num.h>
|
||||
|
||||
typedef ulong (*BcRandUlong)(void*);
|
||||
|
||||
#if BC_LONG_BIT >= 64
|
||||
|
||||
#ifdef BC_RAND_BUILTIN
|
||||
#if BC_RAND_BUILTIN
|
||||
#ifndef __SIZEOF_INT128__
|
||||
#undef BC_RAND_BUILTIN
|
||||
#define BC_RAND_BUILTIN (0)
|
||||
#endif // __SIZEOF_INT128__
|
||||
#endif // BC_RAND_BUILTIN
|
||||
#endif // BC_RAND_BUILTIN
|
||||
|
||||
#ifndef BC_RAND_BUILTIN
|
||||
#ifdef __SIZEOF_INT128__
|
||||
#define BC_RAND_BUILTIN (1)
|
||||
#else // __SIZEOF_INT128__
|
||||
#define BC_RAND_BUILTIN (0)
|
||||
#endif // __SIZEOF_INT128__
|
||||
#endif // BC_RAND_BUILTIN
|
||||
|
||||
typedef uint64_t BcRand;
|
||||
|
||||
#define BC_RAND_ROTC (63)
|
||||
|
||||
#if BC_RAND_BUILTIN
|
||||
|
||||
typedef __uint128_t BcRandState;
|
||||
|
||||
#define bc_rand_mul(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
|
||||
#define bc_rand_add(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
|
||||
|
||||
#define bc_rand_mul2(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
|
||||
#define bc_rand_add2(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
|
||||
|
||||
#define BC_RAND_NOTMODIFIED(r) (((r)->inc & 1UL) == 0)
|
||||
#define BC_RAND_ZERO(r) (!(r)->state)
|
||||
|
||||
#define BC_RAND_CONSTANT(h, l) ((((BcRandState) (h)) << 64) + (BcRandState) (l))
|
||||
|
||||
#define BC_RAND_TRUNC(s) ((uint64_t) (s))
|
||||
#define BC_RAND_CHOP(s) ((uint64_t) ((s) >> 64UL))
|
||||
#define BC_RAND_ROTAMT(s) ((unsigned int) ((s) >> 122UL))
|
||||
|
||||
#else // BC_RAND_BUILTIN
|
||||
|
||||
typedef struct BcRandState {
|
||||
|
||||
uint_fast64_t lo;
|
||||
uint_fast64_t hi;
|
||||
|
||||
} BcRandState;
|
||||
|
||||
#define bc_rand_mul(a, b) (bc_rand_multiply((a), (b)))
|
||||
#define bc_rand_add(a, b) (bc_rand_addition((a), (b)))
|
||||
|
||||
#define bc_rand_mul2(a, b) (bc_rand_multiply2((a), (b)))
|
||||
#define bc_rand_add2(a, b) (bc_rand_addition2((a), (b)))
|
||||
|
||||
#define BC_RAND_NOTMODIFIED(r) (((r)->inc.lo & 1) == 0)
|
||||
#define BC_RAND_ZERO(r) (!(r)->state.lo && !(r)->state.hi)
|
||||
|
||||
#define BC_RAND_CONSTANT(h, l) { .lo = (l), .hi = (h) }
|
||||
|
||||
#define BC_RAND_TRUNC(s) ((s).lo)
|
||||
#define BC_RAND_CHOP(s) ((s).hi)
|
||||
#define BC_RAND_ROTAMT(s) ((unsigned int) ((s).hi >> 58UL))
|
||||
|
||||
#define BC_RAND_BOTTOM32 (((uint_fast64_t) 0xffffffffULL))
|
||||
#define BC_RAND_TRUNC32(n) ((n) & BC_RAND_BOTTOM32)
|
||||
#define BC_RAND_CHOP32(n) ((n) >> 32)
|
||||
|
||||
#endif // BC_RAND_BUILTIN
|
||||
|
||||
#define BC_RAND_MULTIPLIER \
|
||||
BC_RAND_CONSTANT(2549297995355413924ULL, 4865540595714422341ULL)
|
||||
|
||||
#define BC_RAND_FOLD(s) ((BcRand) (BC_RAND_CHOP(s) ^ BC_RAND_TRUNC(s)))
|
||||
|
||||
#else // BC_LONG_BIT >= 64
|
||||
|
||||
#undef BC_RAND_BUILTIN
|
||||
#define BC_RAND_BUILTIN (1)
|
||||
|
||||
typedef uint32_t BcRand;
|
||||
|
||||
#define BC_RAND_ROTC (31)
|
||||
|
||||
typedef uint_fast64_t BcRandState;
|
||||
|
||||
#define bc_rand_mul(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
|
||||
#define bc_rand_add(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
|
||||
|
||||
#define bc_rand_mul2(a, b) (((BcRandState) (a)) * ((BcRandState) (b)))
|
||||
#define bc_rand_add2(a, b) (((BcRandState) (a)) + ((BcRandState) (b)))
|
||||
|
||||
#define BC_RAND_NOTMODIFIED(r) (((r)->inc & 1UL) == 0)
|
||||
#define BC_RAND_ZERO(r) (!(r)->state)
|
||||
|
||||
#define BC_RAND_CONSTANT UINT64_C
|
||||
#define BC_RAND_MULTIPLIER BC_RAND_CONSTANT(6364136223846793005)
|
||||
|
||||
#define BC_RAND_TRUNC(s) ((uint32_t) (s))
|
||||
#define BC_RAND_CHOP(s) ((uint32_t) ((s) >> 32UL))
|
||||
#define BC_RAND_ROTAMT(s) ((unsigned int) ((s) >> 59UL))
|
||||
|
||||
#define BC_RAND_FOLD(s) ((BcRand) ((((s) >> 18U) ^ (s)) >> 27U))
|
||||
|
||||
#endif // BC_LONG_BIT >= 64
|
||||
|
||||
#define BC_RAND_ROT(v, r) \
|
||||
((BcRand) (((v) >> (r)) | ((v) << ((0 - (r)) & BC_RAND_ROTC))))
|
||||
|
||||
#define BC_RAND_BITS (sizeof(BcRand) * CHAR_BIT)
|
||||
#define BC_RAND_STATE_BITS (sizeof(BcRandState) * CHAR_BIT)
|
||||
|
||||
#define BC_RAND_NUM_SIZE (BC_NUM_BIGDIG_LOG10 * 2 + 2)
|
||||
|
||||
#define BC_RAND_SRAND_BITS ((1 << CHAR_BIT) - 1)
|
||||
|
||||
typedef struct BcRNGData {
|
||||
|
||||
BcRandState state;
|
||||
BcRandState inc;
|
||||
|
||||
} BcRNGData;
|
||||
|
||||
typedef struct BcRNG {
|
||||
|
||||
BcVec v;
|
||||
|
||||
} BcRNG;
|
||||
|
||||
void bc_rand_init(BcRNG *r);
|
||||
#ifndef NDEBUG
|
||||
void bc_rand_free(BcRNG *r);
|
||||
#endif // NDEBUG
|
||||
|
||||
BcRand bc_rand_int(BcRNG *r);
|
||||
BcRand bc_rand_bounded(BcRNG *r, BcRand bound);
|
||||
void bc_rand_seed(BcRNG *r, ulong state1, ulong state2, ulong inc1, ulong inc2);
|
||||
void bc_rand_push(BcRNG *r);
|
||||
void bc_rand_pop(BcRNG *r, bool reset);
|
||||
void bc_rand_getRands(BcRNG *r, BcRand *s1, BcRand *s2, BcRand *i1, BcRand *i2);
|
||||
|
||||
extern const BcRandState bc_rand_multiplier;
|
||||
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
#endif // BC_RAND_H
|
59
include/read.h
Normal file
59
include/read.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Code to handle special I/O for bc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_IO_H
|
||||
#define BC_IO_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <status.h>
|
||||
#include <vector.h>
|
||||
|
||||
#ifndef BC_ENABLE_PROMPT
|
||||
#define BC_ENABLE_PROMPT (1)
|
||||
#endif // BC_ENABLE_PROMPT
|
||||
|
||||
#if !BC_ENABLE_PROMPT
|
||||
#define bc_read_line(vec, prompt) bc_read_line(vec)
|
||||
#define bc_read_chars(vec, prompt) bc_read_chars(vec)
|
||||
#endif // BC_ENABLE_PROMPT
|
||||
|
||||
#define BC_READ_BIN_CHAR(c) (((c) < ' ' && !isspace((c))) || ((uchar) c) > '~')
|
||||
|
||||
BcStatus bc_read_line(BcVec *vec, const char *prompt);
|
||||
void bc_read_file(const char *path, char **buf);
|
||||
BcStatus bc_read_chars(BcVec *vec, const char *prompt);
|
||||
|
||||
#endif // BC_IO_H
|
186
include/status.h
Normal file
186
include/status.h
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* All bc status codes.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_STATUS_H
|
||||
#define BC_STATUS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef BC_ENABLED
|
||||
#define BC_ENABLED (1)
|
||||
#endif // BC_ENABLED
|
||||
|
||||
#ifndef DC_ENABLED
|
||||
#define DC_ENABLED (1)
|
||||
#endif // DC_ENABLED
|
||||
|
||||
typedef enum BcStatus {
|
||||
|
||||
BC_STATUS_SUCCESS = 0,
|
||||
BC_STATUS_ERROR_MATH,
|
||||
BC_STATUS_ERROR_PARSE,
|
||||
BC_STATUS_ERROR_EXEC,
|
||||
BC_STATUS_ERROR_FATAL,
|
||||
BC_STATUS_EOF,
|
||||
BC_STATUS_QUIT,
|
||||
|
||||
} BcStatus;
|
||||
|
||||
typedef enum BcError {
|
||||
|
||||
BC_ERROR_MATH_NEGATIVE,
|
||||
BC_ERROR_MATH_NON_INTEGER,
|
||||
BC_ERROR_MATH_OVERFLOW,
|
||||
BC_ERROR_MATH_DIVIDE_BY_ZERO,
|
||||
|
||||
BC_ERROR_FATAL_ALLOC_ERR,
|
||||
BC_ERROR_FATAL_IO_ERR,
|
||||
BC_ERROR_FATAL_FILE_ERR,
|
||||
BC_ERROR_FATAL_BIN_FILE,
|
||||
BC_ERROR_FATAL_PATH_DIR,
|
||||
BC_ERROR_FATAL_OPTION,
|
||||
BC_ERROR_FATAL_OPTION_NO_ARG,
|
||||
BC_ERROR_FATAL_OPTION_ARG,
|
||||
|
||||
BC_ERROR_EXEC_IBASE,
|
||||
BC_ERROR_EXEC_OBASE,
|
||||
BC_ERROR_EXEC_SCALE,
|
||||
BC_ERROR_EXEC_READ_EXPR,
|
||||
BC_ERROR_EXEC_REC_READ,
|
||||
BC_ERROR_EXEC_TYPE,
|
||||
|
||||
BC_ERROR_EXEC_STACK,
|
||||
|
||||
BC_ERROR_EXEC_PARAMS,
|
||||
BC_ERROR_EXEC_UNDEF_FUNC,
|
||||
BC_ERROR_EXEC_VOID_VAL,
|
||||
|
||||
BC_ERROR_PARSE_EOF,
|
||||
BC_ERROR_PARSE_CHAR,
|
||||
BC_ERROR_PARSE_STRING,
|
||||
BC_ERROR_PARSE_COMMENT,
|
||||
BC_ERROR_PARSE_TOKEN,
|
||||
#if BC_ENABLED
|
||||
BC_ERROR_PARSE_EXPR,
|
||||
BC_ERROR_PARSE_EMPTY_EXPR,
|
||||
BC_ERROR_PARSE_PRINT,
|
||||
BC_ERROR_PARSE_FUNC,
|
||||
BC_ERROR_PARSE_ASSIGN,
|
||||
BC_ERROR_PARSE_NO_AUTO,
|
||||
BC_ERROR_PARSE_DUP_LOCAL,
|
||||
BC_ERROR_PARSE_BLOCK,
|
||||
BC_ERROR_PARSE_RET_VOID,
|
||||
BC_ERROR_PARSE_REF_VAR,
|
||||
|
||||
BC_ERROR_POSIX_NAME_LEN,
|
||||
BC_ERROR_POSIX_COMMENT,
|
||||
BC_ERROR_POSIX_KW,
|
||||
BC_ERROR_POSIX_DOT,
|
||||
BC_ERROR_POSIX_RET,
|
||||
BC_ERROR_POSIX_BOOL,
|
||||
BC_ERROR_POSIX_REL_POS,
|
||||
BC_ERROR_POSIX_MULTIREL,
|
||||
BC_ERROR_POSIX_FOR,
|
||||
BC_ERROR_POSIX_EXP_NUM,
|
||||
BC_ERROR_POSIX_REF,
|
||||
BC_ERROR_POSIX_VOID,
|
||||
BC_ERROR_POSIX_BRACE,
|
||||
#endif // BC_ENABLED
|
||||
|
||||
BC_ERROR_NELEMS,
|
||||
|
||||
#if BC_ENABLED
|
||||
BC_ERROR_POSIX_START = BC_ERROR_POSIX_NAME_LEN,
|
||||
BC_ERROR_POSIX_END = BC_ERROR_POSIX_BRACE,
|
||||
#endif // BC_ENABLED
|
||||
|
||||
} BcError;
|
||||
|
||||
#define BC_ERR_IDX_MATH (0)
|
||||
#define BC_ERR_IDX_PARSE (1)
|
||||
#define BC_ERR_IDX_EXEC (2)
|
||||
#define BC_ERR_IDX_FATAL (3)
|
||||
#define BC_ERR_IDX_NELEMS (4)
|
||||
|
||||
#if BC_ENABLED
|
||||
#define BC_ERR_IDX_WARN (BC_ERR_IDX_NELEMS)
|
||||
#endif // BC_ENABLED
|
||||
|
||||
#define BC_UNUSED(e) ((void) (e))
|
||||
|
||||
#ifndef BC_LIKELY
|
||||
#define BC_LIKELY(e) (e)
|
||||
#endif // BC_LIKELY
|
||||
|
||||
#ifndef BC_UNLIKELY
|
||||
#define BC_UNLIKELY(e) (e)
|
||||
#endif // BC_UNLIKELY
|
||||
|
||||
#define BC_ERR(e) BC_UNLIKELY(e)
|
||||
#define BC_NO_ERR(s) BC_LIKELY(s)
|
||||
|
||||
#ifndef BC_DEBUG_CODE
|
||||
#define BC_DEBUG_CODE (0)
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
#if __STDC_VERSION__ >= 201100L
|
||||
#include <stdnoreturn.h>
|
||||
#define BC_NORETURN _Noreturn
|
||||
#else // __STDC_VERSION__
|
||||
#define BC_NORETURN
|
||||
#define BC_MUST_RETURN
|
||||
#endif // __STDC_VERSION__
|
||||
|
||||
// Workarounds for AIX's POSIX incompatibility.
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX __SIZE_MAX__
|
||||
#endif // SIZE_MAX
|
||||
#ifndef UINTMAX_C
|
||||
#define UINTMAX_C __UINTMAX_C
|
||||
#endif // UINTMAX_C
|
||||
#ifndef UINT32_C
|
||||
#define UINT32_C __UINT32_C
|
||||
#endif // UINT32_C
|
||||
#ifndef UINT_FAST32_MAX
|
||||
#define UINT_FAST32_MAX __UINT_FAST32_MAX__
|
||||
#endif // UINT_FAST32_MAX
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX __UINT16_MAX__
|
||||
#endif // UINT16_MAX
|
||||
#ifndef SIG_ATOMIC_MAX
|
||||
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
|
||||
#endif // SIG_ATOMIC_MAX
|
||||
|
||||
#endif // BC_STATUS_H
|
101
include/vector.h
Normal file
101
include/vector.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for bc vectors (resizable arrays).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_VECTOR_H
|
||||
#define BC_VECTOR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <status.h>
|
||||
|
||||
#define BC_VEC_INVALID_IDX (SIZE_MAX)
|
||||
#define BC_VEC_START_CAP (UINTMAX_C(1)<<5)
|
||||
|
||||
typedef unsigned char uchar;
|
||||
|
||||
typedef void (*BcVecFree)(void*);
|
||||
|
||||
// Forward declaration.
|
||||
struct BcId;
|
||||
|
||||
typedef struct BcVec {
|
||||
char *v;
|
||||
size_t len;
|
||||
size_t cap;
|
||||
size_t size;
|
||||
BcVecFree dtor;
|
||||
} BcVec;
|
||||
|
||||
void bc_vec_init(BcVec *restrict v, size_t esize, BcVecFree dtor);
|
||||
void bc_vec_expand(BcVec *restrict v, size_t req);
|
||||
|
||||
void bc_vec_npop(BcVec *restrict v, size_t n);
|
||||
void bc_vec_npopAt(BcVec *restrict v, size_t n, size_t idx);
|
||||
|
||||
void bc_vec_push(BcVec *restrict v, const void *data);
|
||||
void bc_vec_npush(BcVec *restrict v, size_t n, const void *data);
|
||||
void bc_vec_pushByte(BcVec *restrict v, uchar data);
|
||||
void bc_vec_pushIndex(BcVec *restrict v, size_t idx);
|
||||
void bc_vec_string(BcVec *restrict v, size_t len, const char *restrict str);
|
||||
void bc_vec_concat(BcVec *restrict v, const char *restrict str);
|
||||
void bc_vec_empty(BcVec *restrict v);
|
||||
|
||||
#if BC_ENABLE_HISTORY
|
||||
void bc_vec_replaceAt(BcVec *restrict v, size_t idx, const void *data);
|
||||
#endif // BC_ENABLE_HISTORY
|
||||
|
||||
void* bc_vec_item(const BcVec *restrict v, size_t idx);
|
||||
void* bc_vec_item_rev(const BcVec *restrict v, size_t idx);
|
||||
|
||||
void bc_vec_clear(BcVec *restrict v);
|
||||
|
||||
void bc_vec_free(void *vec);
|
||||
|
||||
bool bc_map_insert(BcVec *restrict v, const char *name,
|
||||
size_t idx, size_t *restrict i);
|
||||
size_t bc_map_index(const BcVec *restrict v, const char *name);
|
||||
|
||||
#define bc_vec_pop(v) (bc_vec_npop((v), 1))
|
||||
#define bc_vec_top(v) (bc_vec_item_rev((v), 0))
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define bc_map_init(v) (bc_vec_init((v), sizeof(BcId), bc_id_free))
|
||||
#else // NDEBUG
|
||||
#define bc_map_init(v) (bc_vec_init((v), sizeof(BcId), NULL))
|
||||
#endif // NDEBUG
|
||||
|
||||
#endif // BC_VECTOR_H
|
357
include/vm.h
Normal file
357
include/vm.h
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* *****************************************************************************
|
||||
*
|
||||
* Definitions for bc's VM.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BC_VM_H
|
||||
#define BC_VM_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#if BC_ENABLE_NLS
|
||||
|
||||
# ifdef _WIN32
|
||||
# error NLS is not supported on Windows.
|
||||
# endif // _WIN32
|
||||
|
||||
#include <nl_types.h>
|
||||
|
||||
#endif // BC_ENABLE_NLS
|
||||
|
||||
#include <status.h>
|
||||
#include <num.h>
|
||||
#include <parse.h>
|
||||
#include <program.h>
|
||||
#include <history.h>
|
||||
#include <file.h>
|
||||
|
||||
#if !BC_ENABLED && !DC_ENABLED
|
||||
#error Must define BC_ENABLED, DC_ENABLED, or both
|
||||
#endif
|
||||
|
||||
// CHAR_BIT must be at least 6.
|
||||
#if CHAR_BIT < 6
|
||||
#error CHAR_BIT must be at least 6.
|
||||
#endif
|
||||
|
||||
#ifndef BC_ENABLE_NLS
|
||||
#define BC_ENABLE_NLS (0)
|
||||
#endif // BC_ENABLE_NLS
|
||||
|
||||
#ifndef MAINEXEC
|
||||
#define MAINEXEC bc
|
||||
#endif
|
||||
|
||||
#ifndef EXECPREFIX
|
||||
#define EXECPREFIX
|
||||
#endif
|
||||
|
||||
#define GEN_STR(V) #V
|
||||
#define GEN_STR2(V) GEN_STR(V)
|
||||
|
||||
#define BC_VERSION GEN_STR2(VERSION)
|
||||
#define BC_EXECPREFIX GEN_STR2(EXECPREFIX)
|
||||
#define BC_MAINEXEC GEN_STR2(MAINEXEC)
|
||||
|
||||
// Windows has deprecated isatty().
|
||||
#ifdef _WIN32
|
||||
#define isatty _isatty
|
||||
#endif // _WIN32
|
||||
|
||||
#define DC_FLAG_X (UINTMAX_C(1)<<0)
|
||||
#define BC_FLAG_W (UINTMAX_C(1)<<1)
|
||||
#define BC_FLAG_S (UINTMAX_C(1)<<2)
|
||||
#define BC_FLAG_Q (UINTMAX_C(1)<<3)
|
||||
#define BC_FLAG_L (UINTMAX_C(1)<<4)
|
||||
#define BC_FLAG_I (UINTMAX_C(1)<<5)
|
||||
#define BC_FLAG_G (UINTMAX_C(1)<<6)
|
||||
#define BC_FLAG_P (UINTMAX_C(1)<<7)
|
||||
#define BC_FLAG_TTYIN (UINTMAX_C(1)<<8)
|
||||
#define BC_FLAG_TTY (UINTMAX_C(1)<<9)
|
||||
#define BC_TTYIN (vm.flags & BC_FLAG_TTYIN)
|
||||
#define BC_TTY (vm.flags & BC_FLAG_TTY)
|
||||
|
||||
#define BC_S (BC_ENABLED && (vm.flags & BC_FLAG_S))
|
||||
#define BC_W (BC_ENABLED && (vm.flags & BC_FLAG_W))
|
||||
#define BC_L (BC_ENABLED && (vm.flags & BC_FLAG_L))
|
||||
#define BC_I (vm.flags & BC_FLAG_I)
|
||||
#define BC_G (BC_ENABLED && (vm.flags & BC_FLAG_G))
|
||||
#define DC_X (DC_ENABLED && (vm.flags & DC_FLAG_X))
|
||||
#define BC_P (vm.flags & BC_FLAG_P)
|
||||
|
||||
#define BC_USE_PROMPT (!BC_P && BC_TTY && !BC_IS_POSIX)
|
||||
|
||||
#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#define BC_MAX_OBASE ((BcBigDig) (BC_BASE_POW))
|
||||
#define BC_MAX_DIM ((BcBigDig) (SIZE_MAX - 1))
|
||||
#define BC_MAX_SCALE ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1))
|
||||
#define BC_MAX_STRING ((BcBigDig) (BC_NUM_BIGDIG_MAX - 1))
|
||||
#define BC_MAX_NAME BC_MAX_STRING
|
||||
#define BC_MAX_NUM BC_MAX_SCALE
|
||||
|
||||
#if BC_ENABLE_EXTRA_MATH
|
||||
#define BC_MAX_RAND ((BcBigDig) (((BcRand) 0) - 1))
|
||||
#endif // BC_ENABLE_EXTRA_MATH
|
||||
|
||||
#define BC_MAX_EXP ((ulong) (BC_NUM_BIGDIG_MAX))
|
||||
#define BC_MAX_VARS ((ulong) (SIZE_MAX - 1))
|
||||
|
||||
#define BC_IS_BC (BC_ENABLED && (!DC_ENABLED || vm.name[0] != 'd'))
|
||||
#define BC_IS_POSIX (BC_S || BC_W)
|
||||
|
||||
#if BC_DEBUG_CODE
|
||||
#define BC_VM_JMP bc_vm_jmp(__func__)
|
||||
#else // BC_DEBUG_CODE
|
||||
#define BC_VM_JMP bc_vm_jmp()
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
#define BC_SIG_EXC \
|
||||
BC_UNLIKELY(vm.status != (sig_atomic_t) BC_STATUS_SUCCESS || vm.sig)
|
||||
#define BC_NO_SIG_EXC \
|
||||
BC_LIKELY(vm.status == (sig_atomic_t) BC_STATUS_SUCCESS && !vm.sig)
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define BC_SIG_ASSERT_LOCKED do { assert(vm.sig_lock); } while (0)
|
||||
#define BC_SIG_ASSERT_NOT_LOCKED do { assert(vm.sig_lock == 0); } while (0)
|
||||
#else // NDEBUG
|
||||
#define BC_SIG_ASSERT_LOCKED
|
||||
#define BC_SIG_ASSERT_NOT_LOCKED
|
||||
#endif // NDEBUG
|
||||
|
||||
#define BC_SIG_LOCK \
|
||||
do { \
|
||||
BC_SIG_ASSERT_NOT_LOCKED; \
|
||||
vm.sig_lock = 1; \
|
||||
} while (0)
|
||||
|
||||
#define BC_SIG_UNLOCK \
|
||||
do { \
|
||||
BC_SIG_ASSERT_LOCKED; \
|
||||
vm.sig_lock = 0; \
|
||||
if (BC_SIG_EXC) BC_VM_JMP; \
|
||||
} while (0)
|
||||
|
||||
#define BC_SIG_MAYLOCK \
|
||||
do { \
|
||||
vm.sig_lock = 1; \
|
||||
} while (0)
|
||||
|
||||
#define BC_SIG_MAYUNLOCK \
|
||||
do { \
|
||||
vm.sig_lock = 0; \
|
||||
if (BC_SIG_EXC) BC_VM_JMP; \
|
||||
} while (0)
|
||||
|
||||
#define BC_SIG_TRYLOCK(v) \
|
||||
do { \
|
||||
v = vm.sig_lock; \
|
||||
vm.sig_lock = 1; \
|
||||
} while (0)
|
||||
|
||||
#define BC_SIG_TRYUNLOCK(v) \
|
||||
do { \
|
||||
vm.sig_lock = (v); \
|
||||
if (!(v) && BC_SIG_EXC) BC_VM_JMP; \
|
||||
} while (0)
|
||||
|
||||
#define BC_SETJMP(l) \
|
||||
do { \
|
||||
sigjmp_buf sjb; \
|
||||
BC_SIG_LOCK; \
|
||||
if (sigsetjmp(sjb, 0)) { \
|
||||
assert(BC_SIG_EXC); \
|
||||
goto l; \
|
||||
} \
|
||||
bc_vec_push(&vm.jmp_bufs, &sjb); \
|
||||
BC_SIG_UNLOCK; \
|
||||
} while (0)
|
||||
|
||||
#define BC_SETJMP_LOCKED(l) \
|
||||
do { \
|
||||
sigjmp_buf sjb; \
|
||||
BC_SIG_ASSERT_LOCKED; \
|
||||
if (sigsetjmp(sjb, 0)) { \
|
||||
assert(BC_SIG_EXC); \
|
||||
goto l; \
|
||||
} \
|
||||
bc_vec_push(&vm.jmp_bufs, &sjb); \
|
||||
} while (0)
|
||||
|
||||
#define BC_LONGJMP_CONT \
|
||||
do { \
|
||||
BC_SIG_ASSERT_LOCKED; \
|
||||
if (!vm.sig_pop) bc_vec_pop(&vm.jmp_bufs); \
|
||||
BC_SIG_UNLOCK; \
|
||||
} while (0)
|
||||
|
||||
#define BC_UNSETJMP \
|
||||
do { \
|
||||
BC_SIG_ASSERT_LOCKED; \
|
||||
bc_vec_pop(&vm.jmp_bufs); \
|
||||
} while (0)
|
||||
|
||||
#define BC_LONGJMP_STOP \
|
||||
do { \
|
||||
vm.sig_pop = 0; \
|
||||
vm.sig = 0; \
|
||||
} while (0)
|
||||
|
||||
#define BC_VM_BUF_SIZE (1<<12)
|
||||
#define BC_VM_STDOUT_BUF_SIZE (1<<11)
|
||||
#define BC_VM_STDERR_BUF_SIZE (1<<10)
|
||||
#define BC_VM_STDIN_BUF_SIZE BC_VM_STDERR_BUF_SIZE
|
||||
|
||||
#define bc_vm_err(e) (bc_vm_error((e), 0))
|
||||
#define bc_vm_verr(e, ...) (bc_vm_error((e), 0, __VA_ARGS__))
|
||||
|
||||
#define BC_STATUS_IS_ERROR(s) \
|
||||
((s) >= BC_STATUS_ERROR_MATH && (s) <= BC_STATUS_ERROR_FATAL)
|
||||
|
||||
#define BC_VM_INVALID_CATALOG ((nl_catd) -1)
|
||||
|
||||
// dc does not use is_stdin.
|
||||
#if !BC_ENABLED
|
||||
#define bc_vm_process(text, is_stdin) bc_vm_process(text)
|
||||
#else // BC_ENABLED
|
||||
#endif // BC_ENABLED
|
||||
|
||||
typedef struct BcVm {
|
||||
|
||||
volatile sig_atomic_t status;
|
||||
volatile sig_atomic_t sig_pop;
|
||||
|
||||
BcParse prs;
|
||||
BcProgram prog;
|
||||
|
||||
BcVec jmp_bufs;
|
||||
|
||||
BcVec temps;
|
||||
|
||||
const char* file;
|
||||
|
||||
const char *sigmsg;
|
||||
volatile sig_atomic_t sig_lock;
|
||||
volatile sig_atomic_t sig;
|
||||
uchar siglen;
|
||||
|
||||
uchar read_ret;
|
||||
uint16_t flags;
|
||||
|
||||
uint16_t nchars;
|
||||
uint16_t line_len;
|
||||
|
||||
bool eof;
|
||||
|
||||
BcBigDig maxes[BC_PROG_GLOBALS_LEN + BC_ENABLE_EXTRA_MATH];
|
||||
|
||||
BcVec files;
|
||||
BcVec exprs;
|
||||
|
||||
const char *name;
|
||||
const char *help;
|
||||
|
||||
#if BC_ENABLE_HISTORY
|
||||
BcHistory history;
|
||||
#endif // BC_ENABLE_HISTORY
|
||||
|
||||
BcLexNext next;
|
||||
BcParseParse parse;
|
||||
BcParseExpr expr;
|
||||
|
||||
const char *func_header;
|
||||
|
||||
const char *err_ids[BC_ERR_IDX_NELEMS + BC_ENABLED];
|
||||
const char *err_msgs[BC_ERROR_NELEMS];
|
||||
|
||||
const char *locale;
|
||||
|
||||
BcBigDig last_base;
|
||||
BcBigDig last_pow;
|
||||
BcBigDig last_exp;
|
||||
BcBigDig last_rem;
|
||||
|
||||
char *env_args_buffer;
|
||||
BcVec env_args;
|
||||
|
||||
BcNum max;
|
||||
BcDig max_num[BC_NUM_BIGDIG_LOG10];
|
||||
|
||||
BcFile fout;
|
||||
BcFile ferr;
|
||||
|
||||
#if BC_ENABLE_NLS
|
||||
nl_catd catalog;
|
||||
#endif // BC_ENABLE_NLS
|
||||
|
||||
char *buf;
|
||||
size_t buf_len;
|
||||
|
||||
} BcVm;
|
||||
|
||||
void bc_vm_info(const char* const help);
|
||||
void bc_vm_boot(int argc, char *argv[], const char *env_len,
|
||||
const char* const env_args, const char* env_exp_quit);
|
||||
void bc_vm_shutdown(void);
|
||||
|
||||
void bc_vm_printf(const char *fmt, ...);
|
||||
void bc_vm_putchar(int c);
|
||||
size_t bc_vm_arraySize(size_t n, size_t size);
|
||||
size_t bc_vm_growSize(size_t a, size_t b);
|
||||
void* bc_vm_malloc(size_t n);
|
||||
void* bc_vm_realloc(void *ptr, size_t n);
|
||||
char* bc_vm_strdup(const char *str);
|
||||
|
||||
#if BC_DEBUG_CODE
|
||||
void bc_vm_jmp(const char *f);
|
||||
#else // BC_DEBUG_CODE
|
||||
void bc_vm_jmp(void);
|
||||
#endif // BC_DEBUG_CODE
|
||||
|
||||
void bc_vm_error(BcError e, size_t line, ...);
|
||||
|
||||
extern const char bc_copyright[];
|
||||
extern const char* const bc_err_line;
|
||||
extern const char* const bc_err_func_header;
|
||||
extern const char *bc_errs[];
|
||||
extern const uchar bc_err_ids[];
|
||||
extern const char* const bc_err_msgs[];
|
||||
|
||||
extern BcVm vm;
|
||||
extern char output_bufs[BC_VM_BUF_SIZE];
|
||||
|
||||
#endif // BC_VM_H
|
63
install.sh
Executable file
63
install.sh
Executable file
@ -0,0 +1,63 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
usage() {
|
||||
printf "usage: %s install_dir exec_suffix\n" "$0" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
script="$0"
|
||||
scriptdir=$(dirname "$script")
|
||||
|
||||
. "$scriptdir/functions.sh"
|
||||
|
||||
INSTALL="$scriptdir/safe-install.sh"
|
||||
|
||||
test "$#" -ge 2 || usage
|
||||
|
||||
installdir="$1"
|
||||
shift
|
||||
|
||||
exec_suffix="$1"
|
||||
shift
|
||||
|
||||
bindir="$scriptdir/bin"
|
||||
|
||||
for exe in $bindir/*; do
|
||||
|
||||
base=$(basename "$exe")
|
||||
|
||||
if [ -L "$exe" ]; then
|
||||
link=$(readlink "$exe")
|
||||
"$INSTALL" -Dlm 755 "$link$exec_suffix" "$installdir/$base$exec_suffix"
|
||||
else
|
||||
"$INSTALL" -Dm 755 "$exe" "$installdir/$base$exec_suffix"
|
||||
fi
|
||||
|
||||
done
|
229
karatsuba.py
Executable file
229
karatsuba.py
Executable file
@ -0,0 +1,229 @@
|
||||
#! /usr/bin/python3 -B
|
||||
#
|
||||
# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
def usage():
|
||||
print("usage: {} [num_iterations test_num exe]".format(script))
|
||||
print("\n num_iterations is the number of times to run each karatsuba number; default is 4")
|
||||
print("\n test_num is the last Karatsuba number to run through tests")
|
||||
sys.exit(1)
|
||||
|
||||
def run(cmd, env=None):
|
||||
return subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
|
||||
|
||||
script = sys.argv[0]
|
||||
testdir = os.path.dirname(script)
|
||||
|
||||
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,")
|
||||
print("it takes forever to run.")
|
||||
print("You have been warned.\n")
|
||||
print("Note: If you send an interrupt, it will report the current best number.\n")
|
||||
|
||||
if __name__ != "__main__":
|
||||
usage()
|
||||
|
||||
mx = 520
|
||||
mx2 = mx // 2
|
||||
mn = 16
|
||||
|
||||
num = "9" * mx
|
||||
|
||||
args_idx = 4
|
||||
|
||||
if len(sys.argv) >= 2:
|
||||
num_iterations = int(sys.argv[1])
|
||||
else:
|
||||
num_iterations = 4
|
||||
|
||||
if len(sys.argv) >= 3:
|
||||
test_num = int(sys.argv[2])
|
||||
else:
|
||||
test_num = 0
|
||||
|
||||
if len(sys.argv) >= args_idx:
|
||||
exe = sys.argv[3]
|
||||
else:
|
||||
exe = testdir + "/bin/bc"
|
||||
|
||||
exedir = os.path.dirname(exe)
|
||||
|
||||
indata = "for (i = 0; i < 100; ++i) {} * {}\n"
|
||||
indata += "1.23456789^100000\n1.23456789^100000\nhalt"
|
||||
indata = indata.format(num, num).encode()
|
||||
|
||||
times = []
|
||||
nums = []
|
||||
runs = []
|
||||
nruns = num_iterations + 1
|
||||
|
||||
for i in range(0, nruns):
|
||||
runs.append(0)
|
||||
|
||||
tests = [ "multiply", "modulus", "power", "sqrt" ]
|
||||
scripts = [ "multiply" ]
|
||||
|
||||
print("Testing CFLAGS=\"-flto\"...")
|
||||
|
||||
flags = dict(os.environ)
|
||||
try:
|
||||
flags["CFLAGS"] = flags["CFLAGS"] + " " + "-flto"
|
||||
except KeyError:
|
||||
flags["CFLAGS"] = "-flto"
|
||||
|
||||
p = run([ "./configure.sh", "-O3" ], flags)
|
||||
if p.returncode != 0:
|
||||
print("configure.sh returned an error ({}); exiting...".format(p.returncode))
|
||||
sys.exit(p.returncode)
|
||||
|
||||
p = run([ "make" ])
|
||||
|
||||
if p.returncode == 0:
|
||||
config_env = flags
|
||||
print("Using CFLAGS=\"-flto\"")
|
||||
else:
|
||||
config_env = os.environ
|
||||
print("Not using CFLAGS=\"-flto\"")
|
||||
|
||||
p = run([ "make", "clean" ])
|
||||
|
||||
print("Testing \"make -j4\"")
|
||||
|
||||
if p.returncode != 0:
|
||||
print("make returned an error ({}); exiting...".format(p.returncode))
|
||||
sys.exit(p.returncode)
|
||||
|
||||
p = run([ "make", "-j4" ])
|
||||
|
||||
if p.returncode == 0:
|
||||
makecmd = [ "make", "-j4" ]
|
||||
print("Using \"make -j4\"")
|
||||
else:
|
||||
makecmd = [ "make" ]
|
||||
print("Not using \"make -j4\"")
|
||||
|
||||
if test_num != 0:
|
||||
mx2 = test_num
|
||||
|
||||
try:
|
||||
|
||||
for i in range(mn, mx2 + 1):
|
||||
|
||||
print("\nCompiling...\n")
|
||||
|
||||
p = run([ "./configure.sh", "-O3", "-k{}".format(i) ], config_env)
|
||||
|
||||
if p.returncode != 0:
|
||||
print("configure.sh returned an error ({}); exiting...".format(p.returncode))
|
||||
sys.exit(p.returncode)
|
||||
|
||||
p = run(makecmd)
|
||||
|
||||
if p.returncode != 0:
|
||||
print("make returned an error ({}); exiting...".format(p.returncode))
|
||||
sys.exit(p.returncode)
|
||||
|
||||
if (test_num >= i):
|
||||
|
||||
print("Running tests for Karatsuba Num: {}\n".format(i))
|
||||
|
||||
for test in tests:
|
||||
|
||||
cmd = [ "{}/tests/test.sh".format(testdir), "bc", test, "0", "0", exe ]
|
||||
|
||||
p = subprocess.run(cmd + sys.argv[args_idx:], stderr=subprocess.PIPE)
|
||||
|
||||
if p.returncode != 0:
|
||||
print("{} test failed:\n".format(test, p.returncode))
|
||||
print(p.stderr.decode())
|
||||
print("\nexiting...")
|
||||
sys.exit(p.returncode)
|
||||
|
||||
print("")
|
||||
|
||||
for script in scripts:
|
||||
|
||||
cmd = [ "{}/tests/script.sh".format(testdir), "bc", script + ".bc",
|
||||
"0", "1", "1", "0", exe ]
|
||||
|
||||
p = subprocess.run(cmd + sys.argv[args_idx:], stderr=subprocess.PIPE)
|
||||
|
||||
if p.returncode != 0:
|
||||
print("{} test failed:\n".format(test, p.returncode))
|
||||
print(p.stderr.decode())
|
||||
print("\nexiting...")
|
||||
sys.exit(p.returncode)
|
||||
|
||||
print("")
|
||||
|
||||
elif test_num == 0:
|
||||
|
||||
print("Timing Karatsuba Num: {}".format(i), end='', flush=True)
|
||||
|
||||
for j in range(0, nruns):
|
||||
|
||||
cmd = [ exe, "{}/tests/bc/power.txt".format(testdir) ]
|
||||
|
||||
start = time.perf_counter()
|
||||
p = subprocess.run(cmd, input=indata, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
end = time.perf_counter()
|
||||
|
||||
if p.returncode != 0:
|
||||
print("bc returned an error; exiting...")
|
||||
sys.exit(p.returncode)
|
||||
|
||||
runs[j] = end - start
|
||||
|
||||
run_times = runs[1:]
|
||||
avg = sum(run_times) / len(run_times)
|
||||
|
||||
times.append(avg)
|
||||
nums.append(i)
|
||||
print(", Time: {}".format(times[i - mn]))
|
||||
|
||||
except KeyboardInterrupt:
|
||||
nums = nums[0:i]
|
||||
times = times[0:i]
|
||||
|
||||
if test_num == 0:
|
||||
|
||||
opt = nums[times.index(min(times))]
|
||||
|
||||
print("\n\nOptimal Karatsuba Num (for this machine): {}".format(opt))
|
||||
print("Run the following:\n")
|
||||
if "-flto" in config_env["CFLAGS"]:
|
||||
print("CFLAGS=\"-flto\" ./configure.sh -O3 -k {}".format(opt))
|
||||
else:
|
||||
print("./configure.sh -O3 -k {}".format(opt))
|
||||
print("make")
|
60
link.sh
Executable file
60
link.sh
Executable file
@ -0,0 +1,60 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
usage() {
|
||||
printf "usage: %s bin_dir link\n" "$0" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
test "$#" -gt 1 || usage
|
||||
|
||||
bindir="$1"
|
||||
shift
|
||||
|
||||
link="$1"
|
||||
shift
|
||||
|
||||
|
||||
for exe in "$bindir"/*; do
|
||||
|
||||
if [ ! -L "$exe" ]; then
|
||||
|
||||
base=$(basename "$exe")
|
||||
ext="${base##*.}"
|
||||
|
||||
if [ "$ext" != "$base" ]; then
|
||||
name="$link.$ext"
|
||||
else
|
||||
name="$link"
|
||||
fi
|
||||
|
||||
ln -fs "$base" "$bindir/$name"
|
||||
fi
|
||||
|
||||
done
|
230
locale_install.sh
Executable file
230
locale_install.sh
Executable file
@ -0,0 +1,230 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
usage() {
|
||||
printf "usage: %s NLSPATH main_exec [DESTDIR]\n" "$0" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
gencatfile() {
|
||||
|
||||
_gencatfile_loc="$1"
|
||||
shift
|
||||
|
||||
_gencatfile_file="$1"
|
||||
shift
|
||||
|
||||
mkdir -p $(dirname "$_gencatfile_loc")
|
||||
gencat "$_gencatfile_loc" "$_gencatfile_file" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
localeexists() {
|
||||
|
||||
_localeexists_locales="$1"
|
||||
shift
|
||||
|
||||
_localeexists_locale="$1"
|
||||
shift
|
||||
|
||||
_localeexists_destdir="$1"
|
||||
shift
|
||||
|
||||
if [ "$_localeexists_destdir" != "" ]; then
|
||||
_localeexists_char="@"
|
||||
_localeexists_locale="${_localeexists_locale%%_localeexists_char*}"
|
||||
_localeexists_char="."
|
||||
_localeexists_locale="${_localeexists_locale##*$_localeexists_char}"
|
||||
fi
|
||||
|
||||
test ! -z "${_localeexists_locales##*$_localeexists_locale*}"
|
||||
return $?
|
||||
}
|
||||
|
||||
splitpath() {
|
||||
|
||||
_splitpath_path="$1"
|
||||
shift
|
||||
|
||||
if [ "$_splitpath_path" = "${_splitpath_path#/}" ]; then
|
||||
printf 'Must use absolute paths\n'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${_splitpath_path#\n*}" != "$_splitpath_path" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
_splitpath_list=""
|
||||
_splitpath_item=""
|
||||
|
||||
while [ "$_splitpath_path" != "/" ]; do
|
||||
_splitpath_item=$(basename "$_splitpath_path")
|
||||
_splitpath_list=$(printf '\n%s%s' "$_splitpath_item" "$_splitpath_list")
|
||||
_splitpath_path=$(dirname "$_splitpath_path")
|
||||
done
|
||||
|
||||
if [ "$_splitpath_list" != "/" ]; then
|
||||
_splitpath_list="${_splitpath_list#?}"
|
||||
fi
|
||||
|
||||
printf '%s' "$_splitpath_list"
|
||||
}
|
||||
|
||||
relpath() {
|
||||
|
||||
_relpath_path1="$1"
|
||||
shift
|
||||
|
||||
_relpath_path2="$1"
|
||||
shift
|
||||
|
||||
_relpath_nl=$(printf '\nx')
|
||||
_relpath_nl="${_relpath_nl%x}"
|
||||
|
||||
_relpath_splitpath1=`splitpath "$_relpath_path1"`
|
||||
_relpath_splitpath2=`splitpath "$_relpath_path2"`
|
||||
|
||||
_relpath_path=""
|
||||
_relpath_temp1="$_relpath_splitpath1"
|
||||
|
||||
IFS="$_relpath_nl"
|
||||
|
||||
for _relpath_part in $_relpath_temp1; do
|
||||
|
||||
_relpath_temp2="${_relpath_splitpath2#$_relpath_part$_relpath_nl}"
|
||||
|
||||
if [ "$_relpath_temp2" = "$_relpath_splitpath2" ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
_relpath_splitpath2="$_relpath_temp2"
|
||||
_relpath_splitpath1="${_relpath_splitpath1#$_relpath_part$_relpath_nl}"
|
||||
|
||||
done
|
||||
|
||||
for _relpath_part in $_relpath_splitpath2; do
|
||||
_relpath_path="../$_relpath_path"
|
||||
done
|
||||
|
||||
_relpath_path="${_relpath_path%../}"
|
||||
|
||||
for _relpath_part in $_relpath_splitpath1; do
|
||||
_relpath_path="$_relpath_path$_relpath_part/"
|
||||
done
|
||||
|
||||
_relpath_path="${_relpath_path%/}"
|
||||
|
||||
unset IFS
|
||||
|
||||
printf '%s\n' "$_relpath_path"
|
||||
}
|
||||
|
||||
script="$0"
|
||||
scriptdir=$(dirname "$script")
|
||||
|
||||
. "$scriptdir/functions.sh"
|
||||
|
||||
test "$#" -ge 2 || usage
|
||||
|
||||
nlspath="$1"
|
||||
shift
|
||||
|
||||
main_exec="$1"
|
||||
shift
|
||||
|
||||
if [ "$#" -ge 1 ]; then
|
||||
destdir="$1"
|
||||
shift
|
||||
else
|
||||
destdir=""
|
||||
fi
|
||||
|
||||
"$scriptdir/locale_uninstall.sh" "$nlspath" "$main_exec" "$destdir"
|
||||
|
||||
locales_dir="$scriptdir/locales"
|
||||
|
||||
# What this does is if installing to a package, it installs all locales that
|
||||
# match supported charsets instead of installing all directly supported locales.
|
||||
if [ "$destdir" = "" ]; then
|
||||
locales=$(locale -a)
|
||||
else
|
||||
locales=$(locale -m)
|
||||
fi
|
||||
|
||||
for file in $locales_dir/*.msg; do
|
||||
|
||||
locale=$(basename "$file" ".msg")
|
||||
loc=$(gen_nlspath "$destdir/$nlspath" "$locale" "$main_exec")
|
||||
|
||||
localeexists "$locales" "$locale" "$destdir"
|
||||
err="$?"
|
||||
|
||||
if [ "$err" -eq 0 ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -L "$file" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
gencatfile "$loc" "$file"
|
||||
|
||||
done
|
||||
|
||||
for file in $locales_dir/*.msg; do
|
||||
|
||||
locale=$(basename "$file" ".msg")
|
||||
loc=$(gen_nlspath "$destdir/$nlspath" "$locale" "$main_exec")
|
||||
|
||||
localeexists "$locales" "$locale" "$destdir"
|
||||
err="$?"
|
||||
|
||||
if [ "$err" -eq 0 ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
mkdir -p $(dirname "$loc")
|
||||
|
||||
if [ -L "$file" ]; then
|
||||
|
||||
link=$(readlink "$file")
|
||||
linkdir=$(dirname "$file")
|
||||
locale=$(basename "$link" .msg)
|
||||
linksrc=$(gen_nlspath "$nlspath" "$locale" "$main_exec")
|
||||
relloc="${loc##$destdir/}"
|
||||
rel=$(relpath "$linksrc" "$relloc")
|
||||
|
||||
if [ ! -f "$destdir/$linksrc" ]; then
|
||||
gencatfile "$destdir/$linksrc" "$linkdir/$link"
|
||||
fi
|
||||
|
||||
ln -fs "$rel" "$loc"
|
||||
fi
|
||||
|
||||
done
|
65
locale_uninstall.sh
Executable file
65
locale_uninstall.sh
Executable file
@ -0,0 +1,65 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
usage() {
|
||||
printf "usage: %s NLSPATH main_exec [DESTDIR]\n" "$0" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
script="$0"
|
||||
scriptdir=$(dirname "$script")
|
||||
|
||||
. "$scriptdir/functions.sh"
|
||||
|
||||
INSTALL="$scriptdir/safe-install.sh"
|
||||
|
||||
test "$#" -ge 2 || usage
|
||||
|
||||
nlspath="$1"
|
||||
shift
|
||||
|
||||
main_exec="$1"
|
||||
shift
|
||||
|
||||
if [ "$#" -ge 1 ]; then
|
||||
destdir="$1"
|
||||
shift
|
||||
else
|
||||
destdir=""
|
||||
fi
|
||||
|
||||
# I do something clever here. I am replacing the locale spot with
|
||||
# a wildcard, which should make it search all locale directories.
|
||||
# This way, we can delete catalogs for locales that we had to install
|
||||
# because they are symlinks.
|
||||
locales=$(gen_nlspath "$destdir/$nlspath" "*" "$main_exec")
|
||||
|
||||
for l in $locales; do
|
||||
rm -f "$l"
|
||||
done
|
1
locales/de_AT.ISO8859-1.msg
Symbolic link
1
locales/de_AT.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_DE.ISO8859-1.msg
|
1
locales/de_AT.ISO8859-15.msg
Symbolic link
1
locales/de_AT.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_DE.ISO8859-1.msg
|
1
locales/de_AT.UTF-8.msg
Symbolic link
1
locales/de_AT.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_DE.UTF-8.msg
|
1
locales/de_AT.utf8.msg
Symbolic link
1
locales/de_AT.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_AT.UTF-8.msg
|
1
locales/de_CH.ISO8859-1.msg
Symbolic link
1
locales/de_CH.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_DE.ISO8859-1.msg
|
1
locales/de_CH.ISO8859-15.msg
Symbolic link
1
locales/de_CH.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_DE.ISO8859-1.msg
|
1
locales/de_CH.UTF-8.msg
Symbolic link
1
locales/de_CH.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_DE.UTF-8.msg
|
1
locales/de_CH.utf8.msg
Symbolic link
1
locales/de_CH.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_CH.UTF-8.msg
|
80
locales/de_DE.ISO8859-1.msg
Normal file
80
locales/de_DE.ISO8859-1.msg
Normal file
@ -0,0 +1,80 @@
|
||||
$quote "
|
||||
|
||||
$ Headers for printing errors/warnings.
|
||||
$set 1
|
||||
|
||||
1 "Funktion:"
|
||||
|
||||
$ Error types.
|
||||
$set 2
|
||||
|
||||
1 "Rechenfehler:"
|
||||
2 "Analysefehler:"
|
||||
3 "Laufzeitfehler:"
|
||||
4 "Fataler Fehler:"
|
||||
5 "Warnung:"
|
||||
|
||||
$ Math errors.
|
||||
$set 3
|
||||
|
||||
1 "negative Zahl"
|
||||
2 "Nicht-Ganzzahl-Wert"
|
||||
3 "Überlauf: Zahl passt nicht in Register"
|
||||
4 "Division durch 0"
|
||||
|
||||
$ Parse errors.
|
||||
$set 4
|
||||
|
||||
1 "Ende der Datei"
|
||||
2 "ungültiges Zeichen: '%c'"
|
||||
3 "Zeichenketten-Ende konnte nicht gefunden werden"
|
||||
4 "Kommentar-Ende konnte nicht gefunden werden"
|
||||
5 "ungültiges Token"
|
||||
6 "ungültiger Ausdruck"
|
||||
7 "leerer Ausdruck"
|
||||
8 "Ungültige Druckanweisung"
|
||||
9 "Ungültige Funktionsdefinition"
|
||||
10 "Ungültige Zuweisung: Die linke Seite muss \"scale\", \"ibase\", \"obase\", \"seed\", \"last\", \"var\" oder \"array element\" sein"
|
||||
11 "keine automatische Variable gefunden"
|
||||
12 "Funktionsparameter oder Variable \"%s%s\" existiert bereits"
|
||||
13 "Blockende konnte nicht gefunden werden"
|
||||
14 "eine \"void-Funktion\" kann keinen Wert zurückgeben: %s()"
|
||||
15 "Variable kann keine Referenz sein: %s"
|
||||
16 "POSIX erlaubt keine Namen mit mehr als 1 Zeichen Länge: %s"
|
||||
17 "POSIX erlaubt keine '#'-Skriptkommentare"
|
||||
18 "POSIX erlaubt das Schlüsselwort \"%s\" nicht"
|
||||
19 "POSIX erlaubt keinen Punkt ('.') als Abkürzung für das letzte Ergebnis"
|
||||
20 "POSIX benötigt Klammern um Rückgabeausdrücke"
|
||||
21 "POSIX erlaubt den Operator \"%s\" nicht"
|
||||
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"
|
||||
|
||||
$ Runtime errors.
|
||||
$set 5
|
||||
|
||||
1 "ungültige \"ibase\": muss im Intervall [%lu, %lu] liegen"
|
||||
2 "ungültige \"obase\": muss im Intervall [%lu, %lu] liegen"
|
||||
3 "ungültige \"scale\": muss im Intervall [%lu, %lu] liegen"
|
||||
4 "ungültiger read()-Ausdruck"
|
||||
5 "rekursiver read()-Aufruf"
|
||||
6 "Variable oder Feld-Element hat den falschen Typ"
|
||||
7 "Stapel hat zu wenig Elemente"
|
||||
8 "falsche Anzahl der Parameter: benötigt %zu, hat %zu"
|
||||
9 "undefinierte Funktion: %s()"
|
||||
10 "kann keinen ungültigen Wert in einem Ausdruck verwenden"
|
||||
|
||||
$ Fatal errors.
|
||||
$set 6
|
||||
|
||||
1 "Speicherzuweisung fehlgeschlagen"
|
||||
2 "Ein-Ausgabe-Fehler"
|
||||
3 "konnte die Datei nicht öffnen: %s"
|
||||
4 "Datei ist nicht ASCII: %s"
|
||||
5 "Pfad ist ein Verzeichnis: %s"
|
||||
6 "ungültige Befehlszeilenoption: \"%s\""
|
||||
7 "Option erfordert ein Argument: '%c' (\"%s\")"
|
||||
8 "Option benutzt keine Argumente: '%c' (\"%s\")"
|
1
locales/de_DE.ISO8859-15.msg
Symbolic link
1
locales/de_DE.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_DE.ISO8859-1.msg
|
80
locales/de_DE.UTF-8.msg
Normal file
80
locales/de_DE.UTF-8.msg
Normal file
@ -0,0 +1,80 @@
|
||||
$quote "
|
||||
|
||||
$ Headers for printing errors/warnings.
|
||||
$set 1
|
||||
|
||||
1 "Funktion:"
|
||||
|
||||
$ Error types.
|
||||
$set 2
|
||||
|
||||
1 "Rechenfehler:"
|
||||
2 "Analysefehler:"
|
||||
3 "Laufzeitfehler:"
|
||||
4 "Fataler Fehler:"
|
||||
5 "Warnung:"
|
||||
|
||||
$ Math errors.
|
||||
$set 3
|
||||
|
||||
1 "negative Zahl"
|
||||
2 "Nicht-Ganzzahl-Wert"
|
||||
3 "Überlauf: Zahl passt nicht in Register"
|
||||
4 "Division durch 0"
|
||||
|
||||
$ Parse errors.
|
||||
$set 4
|
||||
|
||||
1 "Ende der Datei"
|
||||
2 "ungültiges Zeichen: '%c'"
|
||||
3 "Zeichenketten-Ende konnte nicht gefunden werden"
|
||||
4 "Kommentar-Ende konnte nicht gefunden werden"
|
||||
5 "ungültiges Token"
|
||||
6 "ungültiger Ausdruck"
|
||||
7 "leerer Ausdruck"
|
||||
8 "Ungültige Druckanweisung"
|
||||
9 "Ungültige Funktionsdefinition"
|
||||
10 "Ungültige Zuweisung: Die linke Seite muss \"scale\", \"ibase\", \"obase\", \"seed\", \"last\", \"var\" oder \"array element\" sein"
|
||||
11 "keine automatische Variable gefunden"
|
||||
12 "Funktionsparameter oder Variable \"%s%s\" existiert bereits"
|
||||
13 "Blockende konnte nicht gefunden werden"
|
||||
14 "eine \"void-Funktion\" kann keinen Wert zurückgeben: %s()"
|
||||
15 "Variable kann keine Referenz sein: %s"
|
||||
16 "POSIX erlaubt keine Namen mit mehr als 1 Zeichen Länge: %s"
|
||||
17 "POSIX erlaubt keine '#'-Skriptkommentare"
|
||||
18 "POSIX erlaubt das Schlüsselwort \"%s\" nicht"
|
||||
19 "POSIX erlaubt keinen Punkt ('.') als Abkürzung für das letzte Ergebnis"
|
||||
20 "POSIX benötigt Klammern um Rückgabeausdrücke"
|
||||
21 "POSIX erlaubt den Operator \"%s\" nicht"
|
||||
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"
|
||||
|
||||
$ Runtime errors.
|
||||
$set 5
|
||||
|
||||
1 "ungültige \"ibase\": muss im Intervall [%lu, %lu] liegen"
|
||||
2 "ungültige \"obase\": muss im Intervall [%lu, %lu] liegen"
|
||||
3 "ungültige \"scale\"; muss im Intervall [%lu, %lu] liegen"
|
||||
4 "ungültiger read()-Ausdruck"
|
||||
5 "rekursiver read()-Aufruf"
|
||||
6 "Variable oder Feld-Element hat den falschen Typ"
|
||||
7 "Stapel hat zu wenig Elemente"
|
||||
8 "falsche Anzahl der Parameter: benötigt %zu, hat %zu"
|
||||
9 "undefinierte Funktion: %s()"
|
||||
10 "kann keinen ungültigen Wert in einem Ausdruck verwenden"
|
||||
|
||||
$ Fatal errors.
|
||||
$set 6
|
||||
|
||||
1 "Speicherzuweisung fehlgeschlagen"
|
||||
2 "Ein-Ausgabe-Fehler"
|
||||
3 "konnte die Datei nicht öffnen: %s"
|
||||
4 "Datei ist nicht ASCII: %s"
|
||||
5 "Pfad ist ein Verzeichnis: %s"
|
||||
6 "ungültige Befehlszeilenoption: \"%s\""
|
||||
7 "Option erfordert ein Argument: '%c' (\"%s\")"
|
||||
8 "Option benutzt keine Argumente: '%c' (\"%s\")"
|
1
locales/de_DE.utf8.msg
Symbolic link
1
locales/de_DE.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
de_DE.UTF-8.msg
|
1
locales/en_AU.ISO8859-1.msg
Symbolic link
1
locales/en_AU.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_AU.ISO8859-15.msg
Symbolic link
1
locales/en_AU.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_AU.US-ASCII.msg
Symbolic link
1
locales/en_AU.US-ASCII.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_AU.UTF-8.msg
Symbolic link
1
locales/en_AU.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_AU.utf8.msg
Symbolic link
1
locales/en_AU.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_AU.UTF-8.msg
|
1
locales/en_CA.ISO8859-1.msg
Symbolic link
1
locales/en_CA.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_CA.ISO8859-15.msg
Symbolic link
1
locales/en_CA.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_CA.US-ASCII.msg
Symbolic link
1
locales/en_CA.US-ASCII.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_CA.UTF-8.msg
Symbolic link
1
locales/en_CA.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_CA.utf8.msg
Symbolic link
1
locales/en_CA.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_CA.UTF-8.msg
|
1
locales/en_GB.ISO8859-1.msg
Symbolic link
1
locales/en_GB.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_GB.ISO8859-15.msg
Symbolic link
1
locales/en_GB.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_GB.US-ASCII.msg
Symbolic link
1
locales/en_GB.US-ASCII.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_GB.UTF-8.msg
Symbolic link
1
locales/en_GB.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_GB.utf8.msg
Symbolic link
1
locales/en_GB.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_GB.UTF-8.msg
|
1
locales/en_IE.ISO8859-1.msg
Symbolic link
1
locales/en_IE.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_IE.ISO8859-15.msg
Symbolic link
1
locales/en_IE.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_IE.US_ASCII.msg
Symbolic link
1
locales/en_IE.US_ASCII.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_IE.UTF-8.msg
Symbolic link
1
locales/en_IE.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_IE.utf8.msg
Symbolic link
1
locales/en_IE.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_IE.UTF-8.msg
|
1
locales/en_NZ.ISO8859-1.msg
Symbolic link
1
locales/en_NZ.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_NZ.ISO8859-15.msg
Symbolic link
1
locales/en_NZ.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_NZ.US-ASCII.msg
Symbolic link
1
locales/en_NZ.US-ASCII.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_NZ.UTF-8.msg
Symbolic link
1
locales/en_NZ.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_NZ.utf8.msg
Symbolic link
1
locales/en_NZ.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_NZ.UTF-8.msg
|
1
locales/en_US.ISO8859-1.msg
Symbolic link
1
locales/en_US.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_US.ISO8859-15.msg
Symbolic link
1
locales/en_US.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_US.US-ASCII.msg
Symbolic link
1
locales/en_US.US-ASCII.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_US.US_ASCII.msg
Symbolic link
1
locales/en_US.US_ASCII.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
1
locales/en_US.UTF-8.msg
Symbolic link
1
locales/en_US.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.msg
|
108
locales/en_US.msg
Normal file
108
locales/en_US.msg
Normal file
@ -0,0 +1,108 @@
|
||||
$ $
|
||||
$ Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
$ $
|
||||
$ All rights reserved.
|
||||
$ $
|
||||
$ Redistribution and use in source and binary forms, with or without
|
||||
$ modification, are permitted provided that the following conditions are met:
|
||||
$ $
|
||||
$ * Redistributions of source code must retain the above copyright notice, this
|
||||
$ list of conditions and the following disclaimer.
|
||||
$ $
|
||||
$ * Redistributions in binary form must reproduce the above copyright notice,
|
||||
$ this list of conditions and the following disclaimer in the documentation
|
||||
$ and/or other materials provided with the distribution.
|
||||
$ $
|
||||
$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
$ POSSIBILITY OF SUCH DAMAGE.
|
||||
$ $
|
||||
|
||||
$quote "
|
||||
|
||||
$ Miscellaneous messages.
|
||||
$set 1
|
||||
|
||||
1 "Function:"
|
||||
|
||||
$ Error types.
|
||||
$set 2
|
||||
|
||||
1 "Math error:"
|
||||
2 "Parse error:"
|
||||
3 "Runtime error:"
|
||||
4 "Fatal error:"
|
||||
5 "Warning:"
|
||||
|
||||
$ Math errors.
|
||||
$set 3
|
||||
|
||||
1 "negative number"
|
||||
2 "non-integer number"
|
||||
3 "overflow: number does not fit into a hardware number"
|
||||
4 "divide by 0"
|
||||
|
||||
$ Parse errors.
|
||||
$set 4
|
||||
|
||||
1 "end of file"
|
||||
2 "invalid character '%c'"
|
||||
3 "string end cannot be found"
|
||||
4 "comment end cannot be found"
|
||||
5 "invalid token"
|
||||
6 "invalid expression"
|
||||
7 "empty expression"
|
||||
8 "invalid print statement"
|
||||
9 "invalid function definition"
|
||||
10 "invalid assignment: left side must be scale, ibase, obase, seed, last, var, or array element"
|
||||
11 "no auto variable found"
|
||||
12 "function parameter or auto \"%s%s\" already exists"
|
||||
13 "block end cannot be found"
|
||||
14 "cannot return a value from void function: %s()"
|
||||
15 "var cannot be a reference: %s"
|
||||
16 "POSIX does not allow names longer than 1 character: %s"
|
||||
17 "POSIX does not allow '#' script comments"
|
||||
18 "POSIX does not allow the following keyword: %s"
|
||||
19 "POSIX does not allow a period ('.') as a shortcut for the last result"
|
||||
20 "POSIX requires parentheses around return expressions"
|
||||
21 "POSIX does not allow the following operator: %s"
|
||||
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"
|
||||
|
||||
$ Runtime errors.
|
||||
$set 5
|
||||
|
||||
1 "invalid ibase: must be [%lu, %lu]"
|
||||
2 "invalid obase: must be [%lu, %lu]"
|
||||
3 "invalid scale: must be [%lu, %lu]"
|
||||
4 "invalid read() expression"
|
||||
5 "recursive read() call"
|
||||
6 "variable or array element is the wrong type"
|
||||
7 "stack has too few elements"
|
||||
8 "wrong number of parameters; need %zu, have %zu"
|
||||
9 "undefined function: %s()"
|
||||
10 "cannot use a void value in an expression"
|
||||
|
||||
$ Fatal errors.
|
||||
$set 6
|
||||
|
||||
1 "memory allocation failed"
|
||||
2 "I/O error"
|
||||
3 "cannot open file: %s"
|
||||
4 "file is not ASCII: %s"
|
||||
5 "path is a directory: %s"
|
||||
6 "invalid command-line option: \"%s\""
|
||||
7 "option requires an argument: '%c' (\"%s\")"
|
||||
8 "option takes no arguments: '%c' (\"%s\")"
|
1
locales/en_US.utf8.msg
Symbolic link
1
locales/en_US.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
en_US.UTF-8.msg
|
108
locales/es_ES.UTF-8.msg
Normal file
108
locales/es_ES.UTF-8.msg
Normal file
@ -0,0 +1,108 @@
|
||||
$ $
|
||||
$ Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
$ $
|
||||
$ All rights reserved.
|
||||
$ $
|
||||
$ Redistribution and use in source and binary forms, with or without
|
||||
$ modification, are permitted provided that the following conditions are met:
|
||||
$ $
|
||||
$ * Redistributions of source code must retain the above copyright notice, this
|
||||
$ list of conditions and the following disclaimer.
|
||||
$ $
|
||||
$ * Redistributions in binary form must reproduce the above copyright notice,
|
||||
$ this list of conditions and the following disclaimer in the documentation
|
||||
$ and/or other materials provided with the distribution.
|
||||
$ $
|
||||
$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
$ POSSIBILITY OF SUCH DAMAGE.
|
||||
$ $
|
||||
|
||||
$quote "
|
||||
|
||||
$ Miscellaneous messages.
|
||||
$set 1
|
||||
|
||||
1 "Función:"
|
||||
|
||||
$ Error types.
|
||||
$set 2
|
||||
|
||||
1 "Error de matemática:"
|
||||
2 "Error de syntaxis:"
|
||||
3 "Error de ejecución:"
|
||||
4 "Error fatal:"
|
||||
5 "Advertencia:"
|
||||
|
||||
$ Math errors.
|
||||
$set 3
|
||||
|
||||
1 "número negativo"
|
||||
2 "número no es entero"
|
||||
3 "desbordamiento de enteros: no se puede encajar el el hardware"
|
||||
4 "división por cero"
|
||||
|
||||
$ Parse errors.
|
||||
$set 4
|
||||
|
||||
1 "fin de archivo"
|
||||
2 "no válido '%c'"
|
||||
3 "no puede encontrar el fine de la cadena"
|
||||
4 "no puede encontrar el fine del comentario"
|
||||
5 "el token no es válido"
|
||||
6 "la expresión no es válida"
|
||||
7 "la expresión es vacía"
|
||||
8 "la expresión de print no es válida"
|
||||
9 "la definición de función no es válida"
|
||||
10 "la asignación no es valida: en la izquierda debe ser scale, ibase, obase, last, var, o un elemento de matriz"
|
||||
11 "no se encontró ninguna variable automática"
|
||||
12 "ya hay un parámetro de función o variable automatica que se llama \"%s%s\""
|
||||
13 "no se puede encontrar el final de del bloque de código"
|
||||
14 "no puede haber un valor de retorno de una función \"void\": %s()"
|
||||
15 "var no puede ser una referencia: %s"
|
||||
16 "POSIX no permite nombres de más de 1 carácter: %s"
|
||||
17 "POSIX no permite '#' script comentarios"
|
||||
18 "POSIX no permite este palabra clave %s"
|
||||
19 "POSIX no permite un punto ('.') como un atajo del resultado previoso"
|
||||
20 "POSIX requieres paréntesis en el expresión del \"return\""
|
||||
21 "POSIX no permite este operador: %s"
|
||||
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"
|
||||
|
||||
$ Runtime errors.
|
||||
$set 5
|
||||
|
||||
1 "\"ibase\" no es válido: debe ser [%lu, %lu]"
|
||||
2 "\"obase\" no es válido: debe ser [%lu, %lu]"
|
||||
3 "\"scale\" no es válido: debe ser [%lu, %lu]"
|
||||
4 "read() expresión no es válido"
|
||||
5 "recursion en la invocación de read()"
|
||||
6 "variable o elemento del matriz de tipo equivocado"
|
||||
7 "la pila no ha demaciado elementos"
|
||||
8 "la función no tiene un número de argumentos correcto; necessita %zu, tiene %zu"
|
||||
9 "la función no esta definida: %s()"
|
||||
10 "no puede utilizar un valor vacío en una expresión"
|
||||
|
||||
$ Fatal errors.
|
||||
$set 6
|
||||
|
||||
1 "error en la asignación de memoria"
|
||||
2 "error de I/O"
|
||||
3 "no puede abrir el archivo: %s"
|
||||
4 "el archivo no es ASCII: %s"
|
||||
5 "el ruta es un directorio: %s"
|
||||
6 "una opción de línea de comandos no es válida: \"%s\""
|
||||
7 "una opción requiere un argumento: '%c' (\"%s\")"
|
||||
8 "una opción no tiene argumento: '%c' (\"%s\")"
|
1
locales/es_ES.utf8.msg
Symbolic link
1
locales/es_ES.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
es_ES.UTF-8.msg
|
1
locales/fr_BE.ISO8859-1.msg
Symbolic link
1
locales/fr_BE.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.ISO8859-1.msg
|
1
locales/fr_BE.ISO8859-15.msg
Symbolic link
1
locales/fr_BE.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.ISO8859-1.msg
|
1
locales/fr_BE.UTF-8.msg
Symbolic link
1
locales/fr_BE.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.UTF-8.msg
|
1
locales/fr_BE.utf8.msg
Symbolic link
1
locales/fr_BE.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_BE.UTF-8.msg
|
1
locales/fr_CA.ISO8859-1.msg
Symbolic link
1
locales/fr_CA.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.ISO8859-1.msg
|
1
locales/fr_CA.ISO8859-15.msg
Symbolic link
1
locales/fr_CA.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.ISO8859-1.msg
|
1
locales/fr_CA.UTF-8.msg
Symbolic link
1
locales/fr_CA.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.UTF-8.msg
|
1
locales/fr_CA.utf8.msg
Symbolic link
1
locales/fr_CA.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_CA.UTF-8.msg
|
1
locales/fr_CH.ISO8859-1.msg
Symbolic link
1
locales/fr_CH.ISO8859-1.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.ISO8859-1.msg
|
1
locales/fr_CH.ISO8859-15.msg
Symbolic link
1
locales/fr_CH.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.ISO8859-1.msg
|
1
locales/fr_CH.UTF-8.msg
Symbolic link
1
locales/fr_CH.UTF-8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.UTF-8.msg
|
1
locales/fr_CH.utf8.msg
Symbolic link
1
locales/fr_CH.utf8.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_CH.UTF-8.msg
|
108
locales/fr_FR.ISO8859-1.msg
Normal file
108
locales/fr_FR.ISO8859-1.msg
Normal file
@ -0,0 +1,108 @@
|
||||
$ $
|
||||
$ Copyright (c) 2018-2020 Gavin D. Howard and contributors.
|
||||
$ $
|
||||
$ All rights reserved.
|
||||
$ $
|
||||
$ Redistribution and use in source and binary forms, with or without
|
||||
$ modification, are permitted provided that the following conditions are met:
|
||||
$ $
|
||||
$ * Redistributions of source code must retain the above copyright notice, this
|
||||
$ list of conditions and the following disclaimer.
|
||||
$ $
|
||||
$ * Redistributions in binary form must reproduce the above copyright notice,
|
||||
$ this list of conditions and the following disclaimer in the documentation
|
||||
$ and/or other materials provided with the distribution.
|
||||
$ $
|
||||
$ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
$ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
$ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
$ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
$ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
$ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
$ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
$ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
$ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
$ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
$ POSSIBILITY OF SUCH DAMAGE.
|
||||
$ $
|
||||
|
||||
$quote "
|
||||
|
||||
$ Miscellaneous messages.
|
||||
$set 1
|
||||
|
||||
1 "Fonction :"
|
||||
|
||||
$ Error types.
|
||||
$set 2
|
||||
|
||||
1 "Erreur de calcul :"
|
||||
2 "Erreur d'analyse syntaxique :"
|
||||
3 "Erreur d'exécution :"
|
||||
4 "Erreur fatale :"
|
||||
5 "Avertissement :"
|
||||
|
||||
$ Math errors.
|
||||
$set 3
|
||||
|
||||
1 "nombre strictement négatif"
|
||||
2 "nombre non entier"
|
||||
3 "dépassement : le nombre ne tient pas dans un type traité par le processeur"
|
||||
4 "division par 0"
|
||||
|
||||
$ Parse errors.
|
||||
$set 4
|
||||
|
||||
1 "fin de fichier"
|
||||
2 "caractère invalide '%c'"
|
||||
3 "fin de chaîne non trouvée"
|
||||
4 "fin de commentaire non trouvée"
|
||||
5 "symbole invalide"
|
||||
6 "expression invalide"
|
||||
7 "expression vide"
|
||||
8 "instruction d'écriture invalide"
|
||||
9 "définition de fonction invalide"
|
||||
10 "affectation invalide : la partie gauche doit être 'scale', 'ibase', 'obase', 'seed', 'last', une variable ou une case de tableau"
|
||||
11 "aucune variable auto trouvée"
|
||||
12 "Le paramètre de fonction ou variable auto \"%s%s\" existe déjà"
|
||||
13 "fin de bloc non trouvée"
|
||||
14 "une fonction 'void' ne peut pas retourner de valeur : %s()"
|
||||
15 "Une variable ne peut pas être une référence : %s"
|
||||
16 "POSIX interdit les noms de plus d'un caractère : %s"
|
||||
17 "POSIX interdit les commentaires dans les scripts (pas de '#')"
|
||||
18 "POSIX interdit le mot-clé '%s'"
|
||||
19 "POSIX interdit l'utilisation du point ('.') comme raccourci pour le dernier résultat"
|
||||
20 "POSIX impose des parenthèses autour des expressions de retour"
|
||||
21 "POSIX interdit l'opérateur '%s'"
|
||||
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"
|
||||
|
||||
$ Runtime errors.
|
||||
$set 5
|
||||
|
||||
1 "ibase invalide : doit être [%lu, %lu]"
|
||||
2 "obase invalide : doit être [%lu, %lu]"
|
||||
3 "scale invalide : doit être [%lu, %lu]"
|
||||
4 "expression read() invalide"
|
||||
5 "appel read() récursif"
|
||||
6 "mauvais type de variable ou d'élément de tableau"
|
||||
7 "pile sous-remplie"
|
||||
8 "nombre incorrect de paramètres - attendus : %zu, obtenus : %zu"
|
||||
9 "fonction non définie : %s()"
|
||||
10 "une valeur 'void' est inutilisable dans une expression"
|
||||
|
||||
$ Fatal errors.
|
||||
$set 6
|
||||
|
||||
1 "échec d'allocation mémoire"
|
||||
2 "erreur d'entrée-sortie"
|
||||
3 "impossible d'ouvrir le fichier : %s"
|
||||
4 "fichier non ASCII : %s"
|
||||
5 "le chemin est un répertoire : %s"
|
||||
6 "option de ligne de commande invalide : \"%s\""
|
||||
7 "l'option '%c' (\"%s\") requiert un argument"
|
||||
8 "l'option '%c' (\"%s\") ne prend pas d'argument"
|
1
locales/fr_FR.ISO8859-15.msg
Symbolic link
1
locales/fr_FR.ISO8859-15.msg
Symbolic link
@ -0,0 +1 @@
|
||||
fr_FR.ISO8859-1.msg
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user