Update to version 3.2.0

This commit is contained in:
Stefan Eßer 2020-11-26 16:52:17 +00:00
parent 9fef4b8de3
commit 04f2650428
98 changed files with 21693 additions and 22905 deletions

1
.gitignore vendored
View File

@ -9,6 +9,7 @@ bin/*bc
bin/*bc.exe
bin/*dc
bin/*dc.exe
bin/bcl
bc.old
*.o
*.a

View File

@ -29,33 +29,13 @@
#
.POSIX:
VERSION = 3.1.6
VERSION = 3.2.0
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
@ -102,6 +82,13 @@ DC = dc
BC_EXEC = $(BIN)/$(EXEC_PREFIX)$(BC)
DC_EXEC = $(BIN)/$(EXEC_PREFIX)$(DC)
LIB = libbcl
LIB_NAME = $(LIB).a
LIBBC = $(BIN)/$(LIB_NAME)
BCL = bcl
BCL_TEST = $(BIN)/$(BCL)
BCL_TEST_C = tests/$(BCL).c
MANUALS = manuals
BC_MANPAGE_NAME = $(EXEC_PREFIX)$(BC)$(EXEC_SUFFIX).1
BC_MANPAGE = $(MANUALS)/$(BC).1
@ -109,16 +96,28 @@ BC_MD = $(BC_MANPAGE).md
DC_MANPAGE_NAME = $(EXEC_PREFIX)$(DC)$(EXEC_SUFFIX).1
DC_MANPAGE = $(MANUALS)/$(DC).1
DC_MD = $(DC_MANPAGE).md
BCL_MANPAGE_NAME = bcl.3
BCL_MANPAGE = $(MANUALS)/$(BCL_MANPAGE_NAME)
BCL_MD = $(BCL_MANPAGE).md
MANPAGE_INSTALL_ARGS = -Dm644
BINARY_INSTALL_ARGS = -Dm755
BCL_HEADER_NAME = bcl.h
BCL_HEADER = include/$(BCL_HEADER_NAME)
%%DESTDIR%%
BINDIR = %%BINDIR%%
INCLUDEDIR = %%INCLUDEDIR%%
LIBDIR = %%LIBDIR%%
MAN1DIR = %%MAN1DIR%%
MAN3DIR = %%MAN3DIR%%
MAIN_EXEC = $(EXEC_PREFIX)$(%%MAIN_EXEC%%)$(EXEC_SUFFIX)
EXEC = $(%%EXEC%%)
NLSPATH = %%NLSPATH%%
BC_ENABLE_LIBRARY = %%LIBRARY%%
BC_ENABLE_HISTORY = %%HISTORY%%
BC_ENABLE_EXTRA_MATH_NAME = BC_ENABLE_EXTRA_MATH
BC_ENABLE_EXTRA_MATH = %%EXTRA_MATH%%
@ -129,7 +128,7 @@ BC_LONG_BIT = %%LONG_BIT%%
RM = rm
MKDIR = mkdir
INSTALL = ./install.sh
INSTALL = ./exec-install.sh
SAFE_INSTALL = ./safe-install.sh
LINK = ./link.sh
MANPAGE = ./manpage.sh
@ -148,7 +147,7 @@ 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)
CPPFLAGS = $(CPPFLAGS7) -DBC_ENABLE_HISTORY=$(BC_ENABLE_HISTORY) -DBC_ENABLE_LIBRARY=$(BC_ENABLE_LIBRARY)
CFLAGS = $(CPPFLAGS) %%CPPFLAGS%% %%CFLAGS%%
LDFLAGS = %%LDFLAGS%%
@ -157,21 +156,24 @@ 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
BC_LIB_C_ARGS = bc_lib bc_lib_name $(BC_ENABLED_NAME) 1
BC_LIB2_C_ARGS = bc_lib2 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)
OBJS = $(BC_HELP_O) $(DC_HELP_O) $(BC_LIB_O) $(BC_LIB2_O) $(OBJ)
OBJ_TARGETS = $(DC_HELP_O) $(BC_HELP_O) $(BC_LIB_O) $(BC_LIB2_O) $(OBJ)
.c.o:
$(CC) $(CFLAGS) -o $@ -c $<
all: make_bin $(OBJ_TARGETS)
all: %%ALL_PREREQ%%
execs: make_bin $(OBJ_TARGETS)
$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o $(EXEC)
%%LINK%%
library: make_bin $(OBJ) $(BC_LIB_O) $(BC_LIB2_O)
ar -r -cu $(LIBBC) $(BC_LIB_O) $(BC_LIB2_O) $(OBJ)
$(GEN_EXEC):
%%GEN_EXEC_TARGET%%
@ -182,10 +184,10 @@ $(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)
$(GEN_EMU) $(GEN_EXEC) $(BC_HELP) $(BC_HELP_C) bc_help "" $(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)
$(GEN_EMU) $(GEN_EXEC) $(DC_HELP) $(DC_HELP_C) dc_help "" $(DC_ENABLED_NAME)
make_bin:
$(MKDIR) -p $(BIN)
@ -222,7 +224,7 @@ help:
check: test
test: test_bc timeconst test_dc
test: %%TESTS%%
test_bc:
%%BC_TEST%%
@ -241,6 +243,12 @@ time_test_dc:
timeconst:
%%TIMECONST%%
library_test: library
$(CC) $(CFLAGS) $(BCL_TEST_C) $(LIBBC) -o $(BCL_TEST)
test_library: library_test
$(BCL_TEST)
valgrind: valgrind_bc valgrind_dc
valgrind_bc:
@ -272,6 +280,7 @@ extra_math:
manpages:
$(MANPAGE) bc
$(MANPAGE) dc
$(MANPAGE) bcl
clean_gen:
@$(RM) -f $(GEN_EXEC)
@ -279,10 +288,6 @@ clean_gen:
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)
@ -343,9 +348,20 @@ install_bc_manpage:
install_dc_manpage:
$(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(DC_MANPAGE) $(DESTDIR)$(MAN1DIR)/$(DC_MANPAGE_NAME)
install:%%INSTALL_LOCALES_PREREQS%%%%INSTALL_PREREQS%%
install_bcl_manpage:
$(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(BCL_MANPAGE) $(DESTDIR)$(MAN3DIR)/$(BCL_MANPAGE_NAME)
install_bcl_header:
$(SAFE_INSTALL) $(MANPAGE_INSTALL_ARGS) $(BCL_HEADER) $(DESTDIR)$(INCLUDEDIR)/$(BCL_HEADER_NAME)
install_execs:
$(INSTALL) $(DESTDIR)$(BINDIR) "$(EXEC_SUFFIX)"
install_library:
$(SAFE_INSTALL) $(BINARY_INSTALL_ARGS) $(LIBBC) $(DESTDIR)$(LIBDIR)/$(LIB_NAME)
install:%%INSTALL_LOCALES_PREREQS%%%%INSTALL_MAN_PREREQS%%%%INSTALL_PREREQS%%
uninstall_locales:
$(LOCALE_UNINSTALL) $(NLSPATH) $(MAIN_EXEC) $(DESTDIR)
@ -361,4 +377,13 @@ uninstall_dc_manpage:
uninstall_dc:
$(RM) -f $(DESTDIR)$(BINDIR)/$(EXEC_PREFIX)$(DC)$(EXEC_SUFFIX)
uninstall_library:
$(RM) -f $(DESTDIR)$(LIBDIR)/$(LIB_NAME)
uninstall_bcl_header:
$(RM) -f $(DESTDIR)$(INCLUDEDIR)/$(BCL_HEADER_NAME)
uninstall_bcl_manpage:
$(RM) -f $(DESTDIR)$(MAN3DIR)/$(BCL_MANPAGE_NAME)
uninstall:%%UNINSTALL_LOCALES_PREREQS%%%%UNINSTALL_MAN_PREREQS%%%%UNINSTALL_PREREQS%%

18
NEWS.md
View File

@ -1,5 +1,23 @@
# News
## 3.2.0
This is a production release that has one bug fix and a major addition.
The bug fix was a missing `auto` variable in the bessel `j()` function in the
math library.
The major addition is a way to build a version of `bc`'s math code as a library.
This is done with the `-a` option to `configure.sh`. The API for the library can
be read in `./manuals/bcl.3.md` or `man bcl` once the library is installed with
`make install`.
This library was requested by developers before I even finished version 1.0, but
I could not figure out how to do it until now.
If the library has API breaking changes, the major version of `bc` will be
incremented.
## 3.1.6
This is a production release that fixes a new warning from Clang 12 for FreeBSD

View File

@ -107,6 +107,23 @@ 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.
### Library
This `bc` does provide a way to build a math library with C bindings. This is
done by the `-a` or `--library` options to `configure.sh`:
```
./configure.sh -a
```
When building the library, the executables are not built. For more information,
see the [build manual][5].
The library API can be found in [`manuals/bcl.3.md`][26] or `man bcl` once the
library is installed.
The library is built as `bin/libbcl.a`.
### Package and Distro Maintainers
#### Recommended Compiler
@ -335,3 +352,4 @@ Folders:
[23]: https://svnweb.freebsd.org/base/head/contrib/bc/
[24]: https://bugs.freebsd.org/
[25]: https://reviews.freebsd.org/
[26]: ./manuals/bcl.3.md

View File

@ -45,22 +45,27 @@ usage() {
_usage_val=0
fi
printf 'usage: %s -h\n' "$script"
printf ' %s --help\n' "$script"
printf ' %s [-bD|-dB|-c] [-EfgGHlMNPT] [-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] [--install-all-locales] \\\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 'usage:\n'
printf ' %s -h\n' "$script"
printf ' %s --help\n' "$script"
printf ' %s [-a|-bD|-dB|-c] [-EfgGHlMNPT] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\n' "$script"
printf ' %s \\\n' "$script"
printf ' [--library|--bc-only --disable-dc|--dc-only --disable-bc|--coverage]\\\n'
printf ' [--force --debug --disable-extra-math --disable-generated-tests] \\\n'
printf ' [--disable-history --disable-man-pages --disable-nls] \\\n'
printf ' [--disable-prompt --disable-strip] [--install-all-locales] \\\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 '\n'
printf ' -a, --library\n'
printf ' Build the libbc instead of the programs. This is meant to be used with\n'
printf ' Other software like programming languages that want to make use of the\n'
printf ' parsing and math capabilities. This option will install headers using\n'
printf ' `make install`.\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 ' Build bc only. It is an error if "-d", "--dc-only", "-B", or\n'
printf ' "--disable-bc" 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'
@ -69,10 +74,10 @@ usage() {
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 ' Build dc only. It is an error if "-b", "--bc-only", "-D", or\n'
printf ' "--disable-dc" 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 ' 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'
@ -122,8 +127,14 @@ usage() {
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 ' The directory to install binaries in. Overrides "$BINDIR" if it exists.\n'
printf ' Default is "$PREFIX/bin".\n'
printf ' --includedir INCLUDEDIR\n'
printf ' The directory to install headers in. Overrides "$INCLUDEDIR" if it\n'
printf ' exists. Default is "$PREFIX/include".\n'
printf ' --libdir LIBDIR\n'
printf ' The directory to install libraries in. Overrides "$LIBDIR" if it exists.\n'
printf ' Default is "$PREFIX/lib".\n'
printf ' --datarootdir DATAROOTDIR\n'
printf ' The root location for data files. Overrides "$DATAROOTDIR" if it exists.\n'
printf ' Default is "$PREFIX/share".\n'
@ -136,6 +147,9 @@ usage() {
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 ' --man3dir MAN3DIR\n'
printf ' The location to install Section 3 manpages to. Overrides "$MAN3DIR" if\n'
printf ' it exists. Default is "$MANDIR/man3".\n'
printf '\n'
printf 'In addition, the following environment variables are used:\n'
printf '\n'
@ -157,12 +171,18 @@ usage() {
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 ' BINDIR The directory to install binaries in. Default is "$PREFIX/bin".\n'
printf ' INCLUDEDIR The directory to install header files in. Default is\n'
printf ' "$PREFIX/include".\n'
printf ' LIBDIR The directory to install libraries in. Default is\n'
printf ' "$PREFIX/lib".\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 ' MAN3DIR The location to install Section 3 manpages to. Default is\n'
printf ' "$MANDIR/man3".\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'
@ -257,56 +277,55 @@ replace() {
substring_replace "$_replace_str" "%%$_replace_needle%%" "$_replace_replacement"
}
gen_file_lists() {
gen_file_list() {
if [ "$#" -lt 3 ]; then
if [ "$#" -lt 1 ]; then
err_exit "Invalid number of args to $0"
fi
_gen_file_lists_contents="$1"
_gen_file_list_contents="$1"
shift
_gen_file_lists_filedir="$1"
shift
p=$(pwd)
_gen_file_lists_typ="$1"
shift
cd "$scriptdir"
# 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
if [ "$#" -ge 1 ]; then
_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")
while [ "$#" -ge 1 ]; do
a="$1"
shift
args="$args ! -wholename src/${a}"
done
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" "")
args="-print"
fi
printf '%s\n' "$_gen_file_lists_contents"
_gen_file_list_needle_src="SRC"
_gen_file_list_needle_obj="OBJ"
_gen_file_list_needle_gcda="GCDA"
_gen_file_list_needle_gcno="GCNO"
_gen_file_list_replacement=$(find src/ -depth -name "*.c" $args | tr '\n' ' ')
_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
"$_gen_file_list_needle_src" "$_gen_file_list_replacement")
_gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "c" "o")
_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
"$_gen_file_list_needle_obj" "$_gen_file_list_replacement")
_gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "o" "gcda")
_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
"$_gen_file_list_needle_gcda" "$_gen_file_list_replacement")
_gen_file_list_replacement=$(replace_exts "$_gen_file_list_replacement" "gcda" "gcno")
_gen_file_list_contents=$(replace "$_gen_file_list_contents" \
"$_gen_file_list_needle_gcno" "$_gen_file_list_replacement")
cd "$p"
printf '%s\n' "$_gen_file_list_contents"
}
bc_only=0
@ -324,10 +343,12 @@ prompt=1
force=0
strip_bin=1
all_locales=0
library=0
while getopts "bBcdDEfgGhHk:lMNO:PST-" opt; do
while getopts "abBcdDEfgGhHk:lMNO:PST-" opt; do
case "$opt" in
a) library=1 ;;
b) bc_only=1 ;;
B) dc_only=1 ;;
c) coverage=1 ;;
@ -352,6 +373,7 @@ while getopts "bBcdDEfgGhHk:lMNO:PST-" opt; do
LONG_OPTARG="${arg#*=}"
case $arg in
help) usage ;;
library) library=1 ;;
bc-only) bc_only=1 ;;
dc-only) dc_only=1 ;;
coverage) coverage=1 ;;
@ -371,6 +393,20 @@ while getopts "bBcdDEfgGhHk:lMNO:PST-" opt; do
fi
BINDIR="$2"
shift ;;
includedir=?*) INCLUDEDIR="$LONG_OPTARG" ;;
includedir)
if [ "$#" -lt 2 ]; then
usage "No argument given for '--$arg' option"
fi
INCLUDEDIR="$2"
shift ;;
libdir=?*) LIBDIR="$LONG_OPTARG" ;;
libdir)
if [ "$#" -lt 2 ]; then
usage "No argument given for '--$arg' option"
fi
LIBDIR="$2"
shift ;;
datarootdir=?*) DATAROOTDIR="$LONG_OPTARG" ;;
datarootdir)
if [ "$#" -lt 2 ]; then
@ -399,6 +435,13 @@ while getopts "bBcdDEfgGhHk:lMNO:PST-" opt; do
fi
MAN1DIR="$2"
shift ;;
man3dir=?*) MAN3DIR="$LONG_OPTARG" ;;
man3dir)
if [ "$#" -lt 2 ]; then
usage "No argument given for '--$arg' option"
fi
MAN3DIR="$2"
shift ;;
localedir=?*) LOCALEDIR="$LONG_OPTARG" ;;
localedir)
if [ "$#" -lt 2 ]; then
@ -454,6 +497,12 @@ if [ "$bc_only" -eq 1 ] && [ "$dc_only" -eq 1 ]; then
usage "Can only specify one of -b(-D) or -d(-B)"
fi
if [ "$library" -ne 0 ]; then
if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then
usage "Must not specify -b(-D) or -d(-B) when building the library"
fi
fi
case $karatsuba_len in
(*[!0-9]*|'') usage "KARATSUBA_LEN is not a number" ;;
(*) ;;
@ -529,6 +578,8 @@ link="@printf 'No link necessary\\\\n'"
main_exec="BC"
executable="BC_EXEC"
tests="test_bc timeconst test_dc"
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)"
@ -567,7 +618,8 @@ if [ "$bc_only" -eq 1 ]; then
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"
install_prereqs=" install_execs"
install_man_prereqs=" install_bc_manpage"
uninstall_prereqs=" uninstall_bc"
uninstall_man_prereqs=" uninstall_bc_manpage"
@ -590,7 +642,8 @@ elif [ "$dc_only" -eq 1 ]; then
timeconst="@printf 'timeconst cannot be run because bc is not built\\\\n'"
install_prereqs=" install_dc_manpage"
install_prereqs=" install_execs"
install_man_prereqs=" install_dc_manpage"
uninstall_prereqs=" uninstall_dc"
uninstall_man_prereqs=" uninstall_dc_manpage"
@ -606,9 +659,18 @@ else
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"
if [ "$library" -eq 0 ]; then
install_prereqs=" install_execs"
install_man_prereqs=" install_bc_manpage install_dc_manpage"
uninstall_prereqs=" uninstall_bc uninstall_dc"
uninstall_man_prereqs=" uninstall_bc_manpage uninstall_dc_manpage"
else
install_prereqs=" install_library install_bcl_header"
install_man_prereqs=" install_bcl_manpage"
uninstall_prereqs=" uninstall_library uninstall_bcl_header"
uninstall_man_prereqs=" uninstall_bcl_manpage"
tests="test_library"
fi
fi
@ -664,6 +726,14 @@ if [ -z "${BINDIR+set}" ]; then
BINDIR="$PREFIX/bin"
fi
if [ -z "${INCLUDEDIR+set}" ]; then
INCLUDEDIR="$PREFIX/include"
fi
if [ -z "${LIBDIR+set}" ]; then
LIBDIR="$PREFIX/lib"
fi
if [ "$install_manpages" -ne 0 ] || [ "$nls" -ne 0 ]; then
if [ -z "${DATAROOTDIR+set}" ]; then
DATAROOTDIR="$PREFIX/share"
@ -684,11 +754,25 @@ if [ "$install_manpages" -ne 0 ]; then
MAN1DIR="$MANDIR/man1"
fi
if [ -z "${MAN3DIR+set}" ]; then
MAN3DIR="$MANDIR/man3"
fi
else
install_prereqs=""
install_man_prereqs=""
uninstall_man_prereqs=""
fi
if [ "$library" -ne 0 ]; then
extra_math=1
nls=0
hist=0
prompt=0
ALL_PREREQ="library"
else
ALL_PREREQ="execs"
fi
if [ "$nls" -ne 0 ]; then
set +e
@ -776,11 +860,11 @@ if [ "$hist" -eq 1 ]; then
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_NLS=$nls -DBC_ENABLE_LIBRARY=0"
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
"$CC" $CPPFLAGS $CFLAGS $flags -c "src/history.c" -o "$scriptdir/history.o" > /dev/null 2>&1
err="$?"
@ -804,7 +888,11 @@ if [ "$hist" -eq 1 ]; then
fi
if [ "$extra_math" -eq 1 ] && [ "$bc" -ne 0 ]; then
if [ "$library" -eq 1 ]; then
bc_lib=""
fi
if [ "$extra_math" -eq 1 ] && [ "$bc" -ne 0 ] && [ "$library" -eq 0 ]; then
BC_LIB2_O="\$(GEN_DIR)/lib2.o"
else
BC_LIB2_O=""
@ -846,6 +934,33 @@ if [ "$manpage_args" = "" ]; then
manpage_args="A"
fi
unneeded=""
if [ "$hist" -eq 0 ]; then
unneeded="$unneeded history.c"
fi
if [ "$bc" -eq 0 ]; then
unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
fi
if [ "$dc" -eq 0 ]; then
unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
fi
if [ "$extra_math" -eq 0 ]; then
unneeded="$unneeded rand.c"
fi
if [ "$library" -ne 0 ]; then
unneeded="$unneeded args.c opt.c read.c file.c main.c"
unneeded="$unneeded lang.c lex.c parse.c program.c"
unneeded="$unneeded bc.c bc_lex.c bc_parse.c"
unneeded="$unneeded dc.c dc_lex.c dc_parse.c"
else
unneeded="$unneeded library.c"
fi
# Print out the values; this is for debugging.
if [ "$bc" -ne 0 ]; then
printf 'Building bc\n'
@ -858,6 +973,7 @@ else
printf 'Not building dc\n'
fi
printf '\n'
printf 'BC_ENABLE_LIBRARY=%s\n\n' "$library"
printf 'BC_ENABLE_HISTORY=%s\n' "$hist"
printf 'BC_ENABLE_EXTRA_MATH=%s\n' "$extra_math"
printf 'BC_ENABLE_NLS=%s\n' "$nls"
@ -873,10 +989,13 @@ printf 'CPPFLAGS=%s\n' "$CPPFLAGS"
printf 'LDFLAGS=%s\n' "$LDFLAGS"
printf 'PREFIX=%s\n' "$PREFIX"
printf 'BINDIR=%s\n' "$BINDIR"
printf 'INCLUDEDIR=%s\n' "$INCLUDEDIR"
printf 'LIBDIR=%s\n' "$LIBDIR"
printf 'DATAROOTDIR=%s\n' "$DATAROOTDIR"
printf 'DATADIR=%s\n' "$DATADIR"
printf 'MANDIR=%s\n' "$MANDIR"
printf 'MAN1DIR=%s\n' "$MAN1DIR"
printf 'MAN3DIR=%s\n' "$MAN3DIR"
printf 'NLSPATH=%s\n' "$NLSPATH"
printf 'EXECSUFFIX=%s\n' "$EXECSUFFIX"
printf 'EXECPREFIX=%s\n' "$EXECPREFIX"
@ -892,16 +1011,17 @@ 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")
if [ "$unneeded" = "" ]; then
contents=$(gen_file_list "$contents" "library.c")
else
contents=$(gen_file_list "$contents" $unneeded)
fi
contents=$(replace "$contents" "BC_ENABLED" "$bc")
contents=$(replace "$contents" "DC_ENABLED" "$dc")
contents=$(replace "$contents" "LINK" "$link")
contents=$(replace "$contents" "LIBRARY" "$library")
contents=$(replace "$contents" "HISTORY" "$hist")
contents=$(replace "$contents" "EXTRA_MATH" "$extra_math")
contents=$(replace "$contents" "NLS" "$nls")
@ -917,7 +1037,10 @@ contents=$(replace "$contents" "DESTDIR" "$destdir")
contents=$(replace "$contents" "EXECSUFFIX" "$EXECSUFFIX")
contents=$(replace "$contents" "EXECPREFIX" "$EXECPREFIX")
contents=$(replace "$contents" "BINDIR" "$BINDIR")
contents=$(replace "$contents" "INCLUDEDIR" "$INCLUDEDIR")
contents=$(replace "$contents" "LIBDIR" "$LIBDIR")
contents=$(replace "$contents" "MAN1DIR" "$MAN1DIR")
contents=$(replace "$contents" "MAN3DIR" "$MAN3DIR")
contents=$(replace "$contents" "CFLAGS" "$CFLAGS")
contents=$(replace "$contents" "HOSTCFLAGS" "$HOSTCFLAGS")
contents=$(replace "$contents" "CPPFLAGS" "$CPPFLAGS")
@ -927,15 +1050,19 @@ 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_MAN_PREREQS" "$install_man_prereqs")
contents=$(replace "$contents" "INSTALL_LOCALES" "$install_locales")
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" "ALL_PREREQ" "$ALL_PREREQ")
contents=$(replace "$contents" "EXECUTABLES" "$executables")
contents=$(replace "$contents" "MAIN_EXEC" "$main_exec")
contents=$(replace "$contents" "EXEC" "$executable")
contents=$(replace "$contents" "TESTS" "$tests")
contents=$(replace "$contents" "BC_TEST" "$bc_test")
contents=$(replace "$contents" "BC_TIME_TEST" "$bc_time_test")

View File

@ -173,7 +173,7 @@ define a(x){
return((m*a+r)/n)
}
define j(n,x){
auto b,s,o,a,i,v,f
auto b,s,o,a,i,r,v,f
b=ibase
ibase=A
s=scale

View File

@ -45,13 +45,14 @@
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";
"// *** AUTOMATICALLY GENERATED FROM %s. DO NOT MODIFY. ***\n\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_label_extern = "extern const char *%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";
static const char* const bc_gen_name_extern = "extern const char %s[];\n\n";
#define IO_ERR (1)
#define INVALID_INPUT_FILE (2)
@ -62,7 +63,7 @@ static const char* const bc_gen_name = "const char %s[] = {\n";
int main(int argc, char *argv[]) {
FILE *in, *out;
char *label, *define, *name, *include;
char *label, *define, *name;
int c, count, slashes, err = IO_ERR;
bool has_label, has_define, remove_tabs;
@ -72,15 +73,14 @@ int main(int argc, char *argv[]) {
}
name = argv[3];
include = argv[4];
has_label = (argc > 5 && strcmp("", argv[5]) != 0);
label = has_label ? argv[5] : "";
has_label = (argc > 4 && strcmp("", argv[4]) != 0);
label = has_label ? argv[4] : "";
has_define = (argc > 6 && strcmp("", argv[6]) != 0);
define = has_define ? argv[6] : "";
has_define = (argc > 5 && strcmp("", argv[5]) != 0);
define = has_define ? argv[5] : "";
remove_tabs = (argc > 7);
remove_tabs = (argc > 6);
in = fopen(argv[1], "r");
if (!in) return INVALID_INPUT_FILE;
@ -89,8 +89,9 @@ int main(int argc, char *argv[]) {
if (!out) goto out_err;
if (fprintf(out, bc_gen_header, argv[1]) < 0) goto err;
if (has_label && fprintf(out, bc_gen_label_extern, label) < 0) goto err;
if (fprintf(out, bc_gen_name_extern, name) < 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;

View File

@ -50,6 +50,7 @@ exec > "$output"
if [ -n "$label" ]; then
nameline="const char *${label} = \"${input}\";"
labelexternline="extern const char *${label};"
fi
if [ -n "$define" ]; then
@ -64,11 +65,14 @@ if [ -n "$remove_tabs" ]; then
fi
cat<<EOF
// Copyright (c) 2018-2020 Gavin D. Howard and contributors.
// Licensed under the 2-clause BSD license.
// *** AUTOMATICALLY GENERATED FROM ${input}. DO NOT MODIFY. ***
${condstart}
#include <${header}>
$labelexternline
extern const char $name[];
$nameline

View File

@ -62,6 +62,4 @@ 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

View File

@ -43,8 +43,8 @@
#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_err(l, e) (bc_vm_handleError((e), (l)->line))
#define bc_lex_verr(l, e, ...) (bc_vm_handleError((e), (l)->line, __VA_ARGS__))
#if BC_ENABLED

View File

@ -45,6 +45,7 @@
#include <status.h>
#include <vector.h>
#include <bcl.h>
#ifndef BC_ENABLE_EXTRA_MATH
#define BC_ENABLE_EXTRA_MATH (1)
@ -54,25 +55,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
typedef BclBigDig BcBigDig;
#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)
@ -80,10 +66,9 @@ typedef uint64_t BcBigDig;
#define BC_NUM_BIGDIG_C UINT64_C
#elif BC_LONG_BIT >= 32
typedef int_least32_t BcDig;
typedef int_least16_t BcDig;
typedef uint32_t BcBigDig;
#elif BC_LONG_BIT >= 32
#define BC_NUM_BIGDIG_MAX ((BcBigDig) UINT32_MAX)
@ -92,6 +77,8 @@ typedef uint32_t BcBigDig;
#define BC_NUM_BIGDIG_C UINT32_C
typedef int_least16_t BcDig;
#else
#error BC_LONG_BIT must be at least 32
@ -106,7 +93,6 @@ typedef struct BcNum {
size_t scale;
size_t len;
size_t cap;
bool neg;
} BcNum;
#if BC_ENABLE_EXTRA_MATH
@ -150,6 +136,30 @@ struct BcRNG;
#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_RDX_VAL(n) ((n)->rdx >> 1)
#define BC_NUM_RDX_VAL_NP(n) ((n).rdx >> 1)
#define BC_NUM_RDX_SET(n, v) \
((n)->rdx = (((v) << 1) | ((n)->rdx & (BcBigDig) 1)))
#define BC_NUM_RDX_SET_NP(n, v) \
((n).rdx = (((v) << 1) | ((n).rdx & (BcBigDig) 1)))
#define BC_NUM_RDX_SET_NEG(n, v, neg) \
((n)->rdx = (((v) << 1) | (neg)))
#define BC_NUM_RDX_VALID(n) \
(BC_NUM_ZERO(n) || BC_NUM_RDX_VAL(n) * BC_BASE_DIGS >= (n)->scale)
#define BC_NUM_RDX_VALID_NP(n) \
((!(n).len) || BC_NUM_RDX_VAL_NP(n) * BC_BASE_DIGS >= (n).scale)
#define BC_NUM_NEG(n) ((n)->rdx & ((BcBigDig) 1))
#define BC_NUM_NEG_NP(n) ((n).rdx & ((BcBigDig) 1))
#define BC_NUM_NEG_CLR(n) ((n)->rdx &= ~((BcBigDig) 1))
#define BC_NUM_NEG_CLR_NP(n) ((n).rdx &= ~((BcBigDig) 1))
#define BC_NUM_NEG_SET(n) ((n)->rdx |= ((BcBigDig) 1))
#define BC_NUM_NEG_TGL(n) ((n)->rdx ^= ((BcBigDig) 1))
#define BC_NUM_NEG_TGL_NP(n) ((n).rdx ^= ((BcBigDig) 1))
#define BC_NUM_NEG_VAL(n, v) (((n)->rdx & ~((BcBigDig) 1)) | (v))
#define BC_NUM_NEG_VAL_NP(n, v) (((n).rdx & ~((BcBigDig) 1)) | (v))
#define BC_NUM_SIZE(n) ((n) * sizeof(BcDig))
#if BC_DEBUG_CODE
@ -183,7 +193,7 @@ void bc_num_bigdig2num(BcNum *restrict n, BcBigDig val);
#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
void bc_num_irand(const BcNum *restrict a, BcNum *restrict b,
struct BcRNG *restrict rng);
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 && BC_ENABLE_RAND
@ -200,28 +210,34 @@ 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_sr(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_divReq(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);
void bc_num_extend(BcNum *restrict n, size_t places);
void bc_num_shiftRight(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_zero(BcNum *restrict n);
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);
bool bc_num_strValid(const char *restrict val);
void bc_num_parse(BcNum *restrict n, const char *restrict val, BcBigDig base);
void bc_num_print(BcNum *restrict n, BcBigDig base, bool newline);
#if DC_ENABLED
void bc_num_stream(BcNum *restrict n, BcBigDig base);
@ -238,6 +254,8 @@ 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 BcDig bc_num_bigdigMax2[];
extern const size_t bc_num_bigdigMax_size;
extern const size_t bc_num_bigdigMax2_size;
#endif // BC_NUM_H

View File

@ -62,8 +62,9 @@
#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__))
#define bc_parse_err(p, e) (bc_vm_handleError((e), (p)->l.line))
#define bc_parse_verr(p, e, ...) \
(bc_vm_handleError((e), (p)->l.line, __VA_ARGS__))
typedef struct BcParseNext {
uchar len;
@ -110,7 +111,7 @@ 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_zero[];
extern const char bc_parse_one[];
extern const char bc_parse_zero[2];
extern const char bc_parse_one[2];
#endif // BC_PARSE_H

View File

@ -223,6 +223,7 @@ 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);
void bc_rand_srand(BcRNGData *rng);
extern const BcRandState bc_rand_multiplier;

View File

@ -46,6 +46,8 @@
#define DC_ENABLED (1)
#endif // DC_ENABLED
#include <bcl.h>
typedef enum BcStatus {
BC_STATUS_SUCCESS = 0,
@ -58,75 +60,75 @@ typedef enum BcStatus {
} BcStatus;
typedef enum BcError {
typedef enum BcErr {
BC_ERROR_MATH_NEGATIVE,
BC_ERROR_MATH_NON_INTEGER,
BC_ERROR_MATH_OVERFLOW,
BC_ERROR_MATH_DIVIDE_BY_ZERO,
BC_ERR_MATH_NEGATIVE,
BC_ERR_MATH_NON_INTEGER,
BC_ERR_MATH_OVERFLOW,
BC_ERR_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_ERR_FATAL_ALLOC_ERR,
BC_ERR_FATAL_IO_ERR,
BC_ERR_FATAL_FILE_ERR,
BC_ERR_FATAL_BIN_FILE,
BC_ERR_FATAL_PATH_DIR,
BC_ERR_FATAL_OPTION,
BC_ERR_FATAL_OPTION_NO_ARG,
BC_ERR_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_ERR_EXEC_IBASE,
BC_ERR_EXEC_OBASE,
BC_ERR_EXEC_SCALE,
BC_ERR_EXEC_READ_EXPR,
BC_ERR_EXEC_REC_READ,
BC_ERR_EXEC_TYPE,
BC_ERROR_EXEC_STACK,
BC_ERR_EXEC_STACK,
BC_ERROR_EXEC_PARAMS,
BC_ERROR_EXEC_UNDEF_FUNC,
BC_ERROR_EXEC_VOID_VAL,
BC_ERR_EXEC_PARAMS,
BC_ERR_EXEC_UNDEF_FUNC,
BC_ERR_EXEC_VOID_VAL,
BC_ERROR_PARSE_EOF,
BC_ERROR_PARSE_CHAR,
BC_ERROR_PARSE_STRING,
BC_ERROR_PARSE_COMMENT,
BC_ERROR_PARSE_TOKEN,
BC_ERR_PARSE_EOF,
BC_ERR_PARSE_CHAR,
BC_ERR_PARSE_STRING,
BC_ERR_PARSE_COMMENT,
BC_ERR_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_ERR_PARSE_EXPR,
BC_ERR_PARSE_EMPTY_EXPR,
BC_ERR_PARSE_PRINT,
BC_ERR_PARSE_FUNC,
BC_ERR_PARSE_ASSIGN,
BC_ERR_PARSE_NO_AUTO,
BC_ERR_PARSE_DUP_LOCAL,
BC_ERR_PARSE_BLOCK,
BC_ERR_PARSE_RET_VOID,
BC_ERR_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,
BC_ERR_POSIX_NAME_LEN,
BC_ERR_POSIX_COMMENT,
BC_ERR_POSIX_KW,
BC_ERR_POSIX_DOT,
BC_ERR_POSIX_RET,
BC_ERR_POSIX_BOOL,
BC_ERR_POSIX_REL_POS,
BC_ERR_POSIX_MULTIREL,
BC_ERR_POSIX_FOR,
BC_ERR_POSIX_EXP_NUM,
BC_ERR_POSIX_REF,
BC_ERR_POSIX_VOID,
BC_ERR_POSIX_BRACE,
#endif // BC_ENABLED
BC_ERROR_NELEMS,
BC_ERR_NELEMS,
#if BC_ENABLED
BC_ERROR_POSIX_START = BC_ERROR_POSIX_NAME_LEN,
BC_ERROR_POSIX_END = BC_ERROR_POSIX_BRACE,
BC_ERR_POSIX_START = BC_ERR_POSIX_NAME_LEN,
BC_ERR_POSIX_END = BC_ERR_POSIX_BRACE,
#endif // BC_ENABLED
} BcError;
} BcErr;
#define BC_ERR_IDX_MATH (0)
#define BC_ERR_IDX_PARSE (1)
@ -163,6 +165,12 @@ typedef enum BcError {
#define BC_MUST_RETURN
#endif // __STDC_VERSION__
#if defined(__clang__) || defined(__GNUC__)
#define BC_FALLTHROUGH __attribute__((fallthrough));
#else // defined(__clang__) || defined(__GNUC__)
#define BC_FALLTHROUGH
#endif //defined(__clang__) || defined(__GNUC__)
// Workarounds for AIX's POSIX incompatibility.
#ifndef SIZE_MAX
#define SIZE_MAX __SIZE_MAX__

View File

@ -62,6 +62,7 @@ typedef struct 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_grow(BcVec *restrict v, size_t n);
void bc_vec_npop(BcVec *restrict v, size_t n);
void bc_vec_npopAt(BcVec *restrict v, size_t n, size_t idx);

View File

@ -36,6 +36,7 @@
#ifndef BC_VM_H
#define BC_VM_H
#include <assert.h>
#include <stddef.h>
#include <limits.h>
@ -56,7 +57,10 @@
#include <parse.h>
#include <program.h>
#include <history.h>
#if !BC_ENABLE_LIBRARY
#include <file.h>
#endif // !BC_ENABLE_LIBRARY
#if !BC_ENABLED && !DC_ENABLED
#error Must define BC_ENABLED, DC_ENABLED, or both
@ -91,6 +95,8 @@
#define isatty _isatty
#endif // _WIN32
#if !BC_ENABLE_LIBRARY
#if DC_ENABLED
#define DC_FLAG_X (UINTMAX_C(1)<<0)
#endif // DC_ENABLED
@ -149,6 +155,8 @@
#define BC_USE_PROMPT (!BC_P && BC_TTY)
#endif // BC_ENABLED
#endif // !BC_ENABLE_LIBRARY
#define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
#define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
@ -270,31 +278,75 @@
#define BC_VM_SAFE_RESULT(r) ((r)->t >= BC_RESULT_TEMP)
#define bc_vm_err(e) (bc_vm_error((e), 0))
#define bc_vm_verr(e, ...) (bc_vm_error((e), 0, __VA_ARGS__))
#if BC_ENABLE_LIBRARY
#define bc_vm_error(e, l, ...) (bc_vm_handleError((e)))
#define bc_vm_err(e) (bc_vm_handleError((e)))
#define bc_vm_verr(e, ...) (bc_vm_handleError((e)))
#else // BC_ENABLE_LIBRARY
#define bc_vm_error(e, l, ...) (bc_vm_handleError((e), (l), __VA_ARGS__))
#define bc_vm_err(e) (bc_vm_handleError((e), 0))
#define bc_vm_verr(e, ...) (bc_vm_handleError((e), 0, __VA_ARGS__))
#endif // BC_ENABLE_LIBRARY
#define BC_STATUS_IS_ERROR(s) \
((s) >= BC_STATUS_ERROR_MATH && (s) <= BC_STATUS_ERROR_FATAL)
#define BC_VM_INVALID_CATALOG ((nl_catd) -1)
#if BC_DEBUG_CODE
#define BC_VM_FUNC_ENTER \
do { \
bc_file_printf(&vm.ferr, "Entering %s\n", __func__); \
bc_file_flush(&vm.ferr); \
} while (0);
#define BC_VM_FUNC_EXIT \
do { \
bc_file_printf(&vm.ferr, "Leaving %s\n", __func__); \
bc_file_flush(&vm.ferr); \
} while (0);
#else // BC_DEBUG_CODE
#define BC_VM_FUNC_ENTER
#define BC_VM_FUNC_EXIT
#endif // BC_DEBUG_CODE
typedef struct BcVm {
volatile sig_atomic_t status;
volatile sig_atomic_t sig_pop;
#if !BC_ENABLE_LIBRARY
BcParse prs;
BcProgram prog;
#endif // BC_ENABLE_LIBRARY
BcVec jmp_bufs;
BcVec temps;
#if BC_ENABLE_LIBRARY
BcVec ctxts;
BcVec out;
BcRNG rng;
BclError err;
bool abrt;
unsigned int refs;
volatile sig_atomic_t running;
#endif // BC_ENABLE_LIBRARY
#if !BC_ENABLE_LIBRARY
const char* file;
const char *sigmsg;
#endif // BC_ENABLE_LIBRARY
volatile sig_atomic_t sig_lock;
volatile sig_atomic_t sig;
#if !BC_ENABLE_LIBRARY
uchar siglen;
uchar read_ret;
@ -305,9 +357,11 @@ typedef struct BcVm {
bool no_exit_exprs;
bool eof;
#endif // BC_ENABLE_LIBRARY
BcBigDig maxes[BC_PROG_GLOBALS_LEN + BC_ENABLE_EXTRA_MATH];
#if !BC_ENABLE_LIBRARY
BcVec files;
BcVec exprs;
@ -325,21 +379,27 @@ typedef struct BcVm {
const char *func_header;
const char *err_ids[BC_ERR_IDX_NELEMS + BC_ENABLED];
const char *err_msgs[BC_ERROR_NELEMS];
const char *err_msgs[BC_ERR_NELEMS];
const char *locale;
#endif // BC_ENABLE_LIBRARY
BcBigDig last_base;
BcBigDig last_pow;
BcBigDig last_exp;
BcBigDig last_rem;
#if !BC_ENABLE_LIBRARY
char *env_args_buffer;
BcVec env_args;
#endif // BC_ENABLE_LIBRARY
BcNum max;
BcNum max2;
BcDig max_num[BC_NUM_BIGDIG_LOG10];
BcDig max2_num[BC_NUM_BIGDIG_LOG10];
#if !BC_ENABLE_LIBRARY
BcFile fout;
BcFile ferr;
@ -349,13 +409,16 @@ typedef struct BcVm {
char *buf;
size_t buf_len;
#endif // !BC_ENABLE_LIBRARY
} 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);
void bc_vm_init(void);
void bc_vm_shutdown(void);
void bc_vm_freeTemps(void);
void bc_vm_printf(const char *fmt, ...);
void bc_vm_putchar(int c);
@ -371,7 +434,11 @@ void bc_vm_jmp(const char *f);
void bc_vm_jmp(void);
#endif // BC_DEBUG_CODE
void bc_vm_error(BcError e, size_t line, ...);
#if BC_ENABLE_LIBRARY
void bc_vm_handleError(BcErr e);
#else // BC_ENABLE_LIBRARY
void bc_vm_handleError(BcErr e, size_t line, ...);
#endif // BC_ENABLE_LIBRARY
extern const char bc_copyright[];
extern const char* const bc_err_line;

View File

@ -32,6 +32,21 @@ usage() {
exit 1
}
print_manpage() {
_print_manpage_md="$1"
shift
_print_manpage_out="$1"
shift
cat "$manualsdir/header.txt" > "$_print_manpage_out"
cat "$manualsdir/header_${manpage}.txt" >> "$_print_manpage_out"
pandoc -f markdown -t man "$_print_manpage_md" >> "$_print_manpage_out"
}
gen_manpage() {
_gen_manpage_args="$1"
@ -84,10 +99,7 @@ gen_manpage() {
IFS="$_gen_manpage_ifs"
cat "$manualsdir/header.txt" > "$_gen_manpage_out"
cat "$manualsdir/header_${manpage}.txt" >> "$_gen_manpage_out"
pandoc -f markdown -t man "$_gen_manpage_md" >> "$_gen_manpage_out"
print_manpage "$_gen_manpage_md" "$_gen_manpage_out"
}
set -e
@ -108,6 +120,12 @@ test "$#" -eq 1 || usage
manpage="$1"
shift
for a in $ARGS; do
gen_manpage "$a"
done
if [ "$manpage" != "bcl" ]; then
for a in $ARGS; do
gen_manpage "$a"
done
else
print_manpage "$manualsdir/${manpage}.3.md" "$manualsdir/${manpage}.3"
fi

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -477,9 +477,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
{{ A H N P HN HP NP HNP }}
In addition, bc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
Using scientific notation is an error or warning if the **-s** or **-w**,
respectively, command-line options (or equivalents) are given.
@ -652,7 +652,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -1019,6 +1019,8 @@ The extended library is a **non-portable extension**.
: Calculates **x** to the power of **y**, even if **y** is not an integer, and
returns the result to the current **scale**.
It is an error if **y** is negative and **x** is **0**.
This is a transcendental function (see the *Transcendental Functions*
subsection below).
@ -1798,7 +1800,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -419,9 +419,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**35**.
In addition, bc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
Using scientific notation is an error or warning if the **-s** or **-w**,
respectively, command-line options (or equivalents) are given.
@ -584,7 +584,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -933,6 +933,8 @@ The extended library is a **non-portable extension**.
: Calculates **x** to the power of **y**, even if **y** is not an integer, and
returns the result to the current **scale**.
It is an error if **y** is negative and **x** is **0**.
This is a transcendental function (see the *Transcendental Functions*
subsection below).
@ -1681,7 +1683,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -457,7 +457,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -1075,7 +1075,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -454,7 +454,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -1059,7 +1059,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -454,7 +454,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -1051,7 +1051,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -450,7 +450,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -1045,7 +1045,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -450,7 +450,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -1053,7 +1053,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -457,7 +457,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -1067,7 +1067,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -453,7 +453,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -1061,7 +1061,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -453,7 +453,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -1069,7 +1069,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -415,9 +415,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**35**.
In addition, bc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
Using scientific notation is an error or warning if the **-s** or **-w**,
respectively, command-line options (or equivalents) are given.
@ -580,7 +580,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -929,6 +929,8 @@ The extended library is a **non-portable extension**.
: Calculates **x** to the power of **y**, even if **y** is not an integer, and
returns the result to the current **scale**.
It is an error if **y** is negative and **x** is **0**.
This is a transcendental function (see the *Transcendental Functions*
subsection below).
@ -1664,7 +1666,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -415,9 +415,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**35**.
In addition, bc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
Using scientific notation is an error or warning if the **-s** or **-w**,
respectively, command-line options (or equivalents) are given.
@ -580,7 +580,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -929,6 +929,8 @@ The extended library is a **non-portable extension**.
: Calculates **x** to the power of **y**, even if **y** is not an integer, and
returns the result to the current **scale**.
It is an error if **y** is negative and **x** is **0**.
This is a transcendental function (see the *Transcendental Functions*
subsection below).
@ -1656,7 +1658,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -411,9 +411,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**35**.
In addition, bc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
Using scientific notation is an error or warning if the **-s** or **-w**,
respectively, command-line options (or equivalents) are given.
@ -576,7 +576,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -925,6 +925,8 @@ The extended library is a **non-portable extension**.
: Calculates **x** to the power of **y**, even if **y** is not an integer, and
returns the result to the current **scale**.
It is an error if **y** is negative and **x** is **0**.
This is a transcendental function (see the *Transcendental Functions*
subsection below).
@ -1650,7 +1652,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -411,9 +411,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**35**.
In addition, bc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
Using scientific notation is an error or warning if the **-s** or **-w**,
respectively, command-line options (or equivalents) are given.
@ -576,7 +576,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -925,6 +925,8 @@ The extended library is a **non-portable extension**.
: Calculates **x** to the power of **y**, even if **y** is not an integer, and
returns the result to the current **scale**.
It is an error if **y** is negative and **x** is **0**.
This is a transcendental function (see the *Transcendental Functions*
subsection below).
@ -1658,7 +1660,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -419,9 +419,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**35**.
In addition, bc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
Using scientific notation is an error or warning if the **-s** or **-w**,
respectively, command-line options (or equivalents) are given.
@ -584,7 +584,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -933,6 +933,8 @@ The extended library is a **non-portable extension**.
: Calculates **x** to the power of **y**, even if **y** is not an integer, and
returns the result to the current **scale**.
It is an error if **y** is negative and **x** is **0**.
This is a transcendental function (see the *Transcendental Functions*
subsection below).
@ -1673,7 +1675,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -415,9 +415,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**35**.
In addition, bc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
Using scientific notation is an error or warning if the **-s** or **-w**,
respectively, command-line options (or equivalents) are given.
@ -580,7 +580,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -929,6 +929,8 @@ The extended library is a **non-portable extension**.
: Calculates **x** to the power of **y**, even if **y** is not an integer, and
returns the result to the current **scale**.
It is an error if **y** is negative and **x** is **0**.
This is a transcendental function (see the *Transcendental Functions*
subsection below).
@ -1667,7 +1669,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# NAME
bc - arbitrary-precision arithmetic language and calculator
bc - arbitrary-precision decimal arithmetic language and calculator
# SYNOPSIS
@ -415,9 +415,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**35**.
In addition, bc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e-3** is equal to **0.0042890**.
Using scientific notation is an error or warning if the **-s** or **-w**,
respectively, command-line options (or equivalents) are given.
@ -580,7 +580,7 @@ The operators will be described in more detail below.
: The **power** operator (not the **exclusive or** operator, as it would be in
C) takes two expressions and raises the first to the power of the value of
the second.
the second. The *scale* of the result is equal to **scale**.
The second expression must be an integer (no *scale*), and if it is
negative, the first value must be non-zero.
@ -929,6 +929,8 @@ The extended library is a **non-portable extension**.
: Calculates **x** to the power of **y**, even if **y** is not an integer, and
returns the result to the current **scale**.
It is an error if **y** is negative and **x** is **0**.
This is a transcendental function (see the *Transcendental Functions*
subsection below).
@ -1675,7 +1677,7 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHORS
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html
[2]: https://www.gnu.org/software/bc/

View File

@ -282,6 +282,29 @@ following forms:
--option=arg
```
### Library
To build the math library, use the following commands for the configure step:
```
./configure.sh -a
./configure.sh --library
```
Both commands are equivalent.
When the library is built, history, prompt, and locales are disabled, and the
functionality for `bc` and `dc` are both enabled, though the executables are
*not* built. This is because the library's options clash with the executables.
To build an optimized version of the library, users can pass optimization
options to `configure.sh` or include them in `CFLAGS`.
The library API can be found in `manuals/bcl.3.md` or `man bcl` once the library
is installed.
The library is built as `bin/libbcl.a`.
### `bc` Only
To build `bc` only (no `dc`), use any one of the following commands for the

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -235,9 +235,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
{{ A H N P HN HP NP HNP }}
In addition, dc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**WARNING**: Both the number and the exponent in scientific notation are
interpreted according to the current **ibase**, but the number is still
@ -355,7 +355,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1252,6 +1253,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -222,9 +222,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**15**.
In addition, dc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**WARNING**: Both the number and the exponent in scientific notation are
interpreted according to the current **ibase**, but the number is still
@ -339,7 +339,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1189,6 +1190,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -289,7 +289,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1025,6 +1026,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -289,7 +289,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1012,6 +1013,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -289,7 +289,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1007,6 +1008,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -286,7 +286,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1002,6 +1003,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -286,7 +286,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1007,6 +1008,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -289,7 +289,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1020,6 +1021,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -286,7 +286,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1015,6 +1016,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -286,7 +286,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1020,6 +1021,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -222,9 +222,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**15**.
In addition, dc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**WARNING**: Both the number and the exponent in scientific notation are
interpreted according to the current **ibase**, but the number is still
@ -339,7 +339,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1176,6 +1177,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -222,9 +222,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**15**.
In addition, dc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**WARNING**: Both the number and the exponent in scientific notation are
interpreted according to the current **ibase**, but the number is still
@ -339,7 +339,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1171,6 +1172,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -219,9 +219,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**15**.
In addition, dc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**WARNING**: Both the number and the exponent in scientific notation are
interpreted according to the current **ibase**, but the number is still
@ -336,7 +336,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1166,6 +1167,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -219,9 +219,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**15**.
In addition, dc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**WARNING**: Both the number and the exponent in scientific notation are
interpreted according to the current **ibase**, but the number is still
@ -336,7 +336,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1171,6 +1172,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -222,9 +222,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**15**.
In addition, dc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**WARNING**: Both the number and the exponent in scientific notation are
interpreted according to the current **ibase**, but the number is still
@ -339,7 +339,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1184,6 +1185,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -219,9 +219,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**15**.
In addition, dc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**WARNING**: Both the number and the exponent in scientific notation are
interpreted according to the current **ibase**, but the number is still
@ -336,7 +336,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1179,6 +1180,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
# Name
dc - arbitrary-precision reverse-Polish notation calculator
dc - arbitrary-precision decimal reverse-Polish notation calculator
# SYNOPSIS
@ -219,9 +219,9 @@ if they were valid digits, regardless of the value of **ibase**. This means that
**15**.
In addition, dc(1) accepts numbers in scientific notation. These have the form
**\<number\>e\<integer\>**. The power (the portion after the **e**) must be an
integer. An example is **1.89237e9**, which is equal to **1892370000**. Negative
exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**\<number\>e\<integer\>**. The exponent (the portion after the **e**) must be
an integer. An example is **1.89237e9**, which is equal to **1892370000**.
Negative exponents are also allowed, so **4.2890e_3** is equal to **0.0042890**.
**WARNING**: Both the number and the exponent in scientific notation are
interpreted according to the current **ibase**, but the number is still
@ -336,7 +336,8 @@ These are the commands used for arithmetic.
**\^**
: The top two values are popped off the stack, the second is raised to the
power of the first, and the result is pushed onto the stack.
power of the first, and the result is pushed onto the stack. The *scale* of
the result is equal to **scale**.
The first value popped off of the stack must be an integer, and if that
value is negative, the second value popped off of the stack must be
@ -1184,6 +1185,6 @@ None are known. Report bugs at https://git.yzena.com/gavin/bc.
# AUTHOR
Gavin D. Howard <yzena.tech@gmail.com> and contributors.
Gavin D. Howard <gavin@yzena.com> and contributors.
[1]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html

View File

@ -263,6 +263,35 @@ runtestseries() {
done
}
runlibtests() {
_runlibtests_CFLAGS="$1"
shift
_runlibtests_CC="$1"
shift
_runlibtests_configure_flags="$1"
shift
_runlibtests_run_tests="$1"
shift
_runlibtests_configure_flags="$_runlibtests_configure_flags -a"
build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 64
if [ "$_runlibtests_run_tests" -ne 0 ]; then
runtest
fi
build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 32
if [ "$_runlibtests_run_tests" -ne 0 ]; then
runtest
fi
}
runtests() {
_runtests_CFLAGS="$1"
@ -326,6 +355,12 @@ debug() {
if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then
runtests "$debug -fsanitize=undefined" "$_debug_CC" "-g" "$_debug_run_tests"
fi
runlibtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests"
if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then
runlibtests "$debug -fsanitize=undefined" "$_debug_CC" "-g" "$_debug_run_tests"
fi
}
release() {
@ -337,6 +372,8 @@ release() {
shift
runtests "$release" "$_release_CC" "-O3" "$_release_run_tests"
runlibtests "$release" "$_release_CC" "-O3" "$_release_run_tests"
}
reldebug() {
@ -353,6 +390,13 @@ reldebug() {
runtests "$debug -fsanitize=address" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
runtests "$debug -fsanitize=memory" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
fi
runlibtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then
runlibtests "$debug -fsanitize=address" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
runlibtests "$debug -fsanitize=memory" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests"
fi
}
minsize() {
@ -364,6 +408,8 @@ minsize() {
shift
runtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests"
runlibtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests"
}
build_set() {

View File

@ -41,10 +41,8 @@
#include <unistd.h>
#include <status.h>
#include <vector.h>
#include <read.h>
#include <vm.h>
#include <args.h>
#include <opt.h>
@ -109,7 +107,7 @@ void bc_args(int argc, char *argv[]) {
case 'e':
{
if (vm.no_exit_exprs)
bc_vm_verr(BC_ERROR_FATAL_OPTION, "-e (--expression)");
bc_vm_verr(BC_ERR_FATAL_OPTION, "-e (--expression)");
bc_args_exprs(opts.optarg);
break;
}
@ -119,7 +117,7 @@ void bc_args(int argc, char *argv[]) {
if (!strcmp(opts.optarg, "-")) vm.no_exit_exprs = true;
else {
if (vm.no_exit_exprs)
bc_vm_verr(BC_ERROR_FATAL_OPTION, "-f (--file)");
bc_vm_verr(BC_ERR_FATAL_OPTION, "-f (--file)");
bc_args_file(opts.optarg);
}
break;

View File

@ -43,6 +43,8 @@
#include <program.h>
#include <vm.h>
#if !BC_ENABLE_LIBRARY
#if BC_ENABLED
const char bc_sig_msg[] = "\ninterrupt (type \"quit\" to exit)\n";
const uchar bc_sig_msg_len = (uchar) (sizeof(bc_sig_msg) - 1);
@ -664,11 +666,8 @@ const char* bc_inst_names[] = {
};
#endif // BC_DEBUG_CODE
#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
const BcRandState bc_rand_multiplier = BC_RAND_MULTIPLIER;
#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
const char bc_parse_zero[2] = "0";
const char bc_parse_one[2] = "1";
#if BC_ENABLED
const BcLexKeyword bc_lex_kws[] = {
@ -712,8 +711,6 @@ const BcLexKeyword bc_lex_kws[] = {
const size_t bc_lex_kws_len = sizeof(bc_lex_kws) / sizeof(BcLexKeyword);
const char* const bc_parse_const1 = "1";
// This is an array that corresponds to token types. An entry is
// true if the token is valid in an expression, false otherwise.
const uint8_t bc_parse_exprs[] = {
@ -937,11 +934,26 @@ const uchar dc_parse_insts[] = {
};
#endif // DC_ENABLED
#endif // !BC_ENABLE_LIBRARY
#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
const BcRandState bc_rand_multiplier = BC_RAND_MULTIPLIER;
#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
#if BC_LONG_BIT >= 64
const BcDig bc_num_bigdigMax[] = {
709551616U,
446744073U,
18U
18U,
};
const BcDig bc_num_bigdigMax2[] = {
768211456U,
374607431U,
938463463U,
282366920U,
340U,
};
#else // BC_LONG_BIT >= 64
const BcDig bc_num_bigdigMax[] = {
@ -949,12 +961,17 @@ const BcDig bc_num_bigdigMax[] = {
9496U,
42U,
};
const BcDig bc_num_bigdigMax2[] = {
1616U,
955U,
737U,
6744U,
1844U,
};
#endif // BC_LONG_BIT >= 64
const size_t bc_num_bigdigMax_size = sizeof(bc_num_bigdigMax) / sizeof(BcDig);
const char bc_parse_zero[] = "0";
const char bc_parse_one[] = "1";
const size_t bc_num_bigdigMax2_size = sizeof(bc_num_bigdigMax2) / sizeof(BcDig);
const char bc_num_hex_digits[] = "0123456789ABCDEF";
@ -973,6 +990,8 @@ const BcBigDig bc_num_pow10[BC_BASE_DIGS + 1] = {
#endif // BC_BASE_DIGS > 4
};
#if !BC_ENABLE_LIBRARY
const BcNumBinaryOp bc_program_ops[] = {
bc_num_pow, bc_num_mul, bc_num_div, bc_num_mod, bc_num_add, bc_num_sub,
#if BC_ENABLE_EXTRA_MATH
@ -981,7 +1000,7 @@ const BcNumBinaryOp bc_program_ops[] = {
};
const BcNumBinaryOpReq bc_program_opReqs[] = {
bc_num_powReq, bc_num_mulReq, bc_num_mulReq, bc_num_mulReq,
bc_num_powReq, bc_num_mulReq, bc_num_divReq, bc_num_divReq,
bc_num_addReq, bc_num_addReq,
#if BC_ENABLE_EXTRA_MATH
bc_num_placesReq, bc_num_placesReq, bc_num_placesReq,
@ -1002,3 +1021,5 @@ const char bc_program_ready_msg[] = "ready for more input\n";
const size_t bc_program_ready_msg_len = sizeof(bc_program_ready_msg) - 1;
const char bc_program_esc_chars[] = "ab\\efnqrt";
const char bc_program_esc_seqs[] = "\a\b\\\\\f\n\"\r\t";
#endif // !BC_ENABLE_LIBRARY

View File

@ -41,8 +41,8 @@
#include <file.h>
#include <vm.h>
void bc_file_ultoa(unsigned long long val, char buf[BC_FILE_ULL_LENGTH]) {
static void bc_file_ultoa(unsigned long long val, char buf[BC_FILE_ULL_LENGTH])
{
char buf2[BC_FILE_ULL_LENGTH];
size_t i, len;
@ -105,7 +105,7 @@ void bc_file_flush(BcFile *restrict f) {
vm.status = (sig_atomic_t) s;
BC_VM_JMP;
}
else bc_vm_err(BC_ERROR_FATAL_IO_ERR);
else bc_vm_err(BC_ERR_FATAL_IO_ERR);
}
}

View File

@ -77,7 +77,7 @@ void bc_func_insert(BcFunc *f, BcProgram *p, char *name,
BcLoc *id = bc_vec_item(&f->autos, i);
if (BC_ERR(idx == id->loc && type == (BcType) id->idx)) {
const char *array = type == BC_TYPE_ARRAY ? "[]" : "";
bc_vm_error(BC_ERROR_PARSE_DUP_LOCAL, line, name, array);
bc_vm_error(BC_ERR_PARSE_DUP_LOCAL, line, name, array);
}
}

View File

@ -38,14 +38,13 @@
#include <stdbool.h>
#include <string.h>
#include <status.h>
#include <lex.h>
#include <vm.h>
#include <bc.h>
void bc_lex_invalidChar(BcLex *l, char c) {
l->t = BC_LEX_INVALID;
bc_lex_verr(l, BC_ERROR_PARSE_CHAR, c);
bc_lex_verr(l, BC_ERR_PARSE_CHAR, c);
}
void bc_lex_lineComment(BcLex *l) {
@ -69,7 +68,7 @@ void bc_lex_comment(BcLex *l) {
if (BC_ERR(!c || buf[i + 1] == '\0')) {
l->i = i;
bc_lex_err(l, BC_ERROR_PARSE_COMMENT);
bc_lex_err(l, BC_ERR_PARSE_COMMENT);
}
end = buf[i + 1] == '/';
@ -143,7 +142,7 @@ void bc_lex_number(BcLex *l, char start) {
if (c == 'e') {
#if BC_ENABLED
if (BC_IS_POSIX) bc_lex_err(l, BC_ERROR_POSIX_EXP_NUM);
if (BC_IS_POSIX) bc_lex_err(l, BC_ERR_POSIX_EXP_NUM);
#endif // BC_ENABLED
bc_vec_push(&l->str, &c);
@ -157,7 +156,7 @@ void bc_lex_number(BcLex *l, char start) {
}
if (BC_ERR(!BC_LEX_NUM_CHAR(c, false, true)))
bc_lex_verr(l, BC_ERROR_PARSE_CHAR, c);
bc_lex_verr(l, BC_ERR_PARSE_CHAR, c);
l->i += bc_lex_num(l, 0, true);
}
@ -208,7 +207,7 @@ void bc_lex_next(BcLex *l) {
l->last = l->t;
l->line += (l->i != 0 && l->buf[l->i - 1] == '\n');
if (BC_ERR(l->last == BC_LEX_EOF)) bc_lex_err(l, BC_ERROR_PARSE_EOF);
if (BC_ERR(l->last == BC_LEX_EOF)) bc_lex_err(l, BC_ERR_PARSE_EOF);
l->t = BC_LEX_EOF;

View File

@ -47,9 +47,6 @@
#include <bc.h>
#include <dc.h>
char output_bufs[BC_VM_BUF_SIZE];
BcVm vm;
int main(int argc, char *argv[]) {
int s;

562
src/num.c

File diff suppressed because it is too large Load Diff

View File

@ -62,8 +62,8 @@ static const char* bc_opt_longopt(const BcOptLong *longopts, int c) {
return "NULL";
}
static void bc_opt_error(BcError err, int c, const char *str) {
if (err == BC_ERROR_FATAL_OPTION) bc_vm_error(err, 0, str);
static void bc_opt_error(BcErr err, int c, const char *str) {
if (err == BC_ERR_FATAL_OPTION) bc_vm_error(err, 0, str);
else bc_vm_error(err, 0, (int) c, str);
}
@ -110,10 +110,12 @@ static int bc_opt_parseShort(BcOpt *o, const BcOptLong *longopts) {
str[0] = option[0];
o->optind += 1;
bc_opt_error(BC_ERROR_FATAL_OPTION, option[0], str);
bc_opt_error(BC_ERR_FATAL_OPTION, option[0], str);
}
}
// Fallthrough.
BC_FALLTHROUGH
case BC_OPT_NONE:
{
if (option[1]) o->subopt += 1;
@ -136,7 +138,7 @@ static int bc_opt_parseShort(BcOpt *o, const BcOptLong *longopts) {
o->optarg = next;
o->optind += 1;
}
else bc_opt_error(BC_ERROR_FATAL_OPTION_NO_ARG, option[0],
else bc_opt_error(BC_ERR_FATAL_OPTION_NO_ARG, option[0],
bc_opt_longopt(longopts, option[0]));
@ -215,12 +217,12 @@ int bc_opt_parse(BcOpt *o, const BcOptLong *longopts) {
if ((longopts[i].type == BC_OPT_BC_ONLY && BC_IS_DC) ||
(longopts[i].type == BC_OPT_DC_ONLY && BC_IS_BC))
{
bc_opt_error(BC_ERROR_FATAL_OPTION, o->optopt, name);
bc_opt_error(BC_ERR_FATAL_OPTION, o->optopt, name);
}
if (longopts[i].type == BC_OPT_NONE && arg != NULL)
{
bc_opt_error(BC_ERROR_FATAL_OPTION_ARG, o->optopt, name);
bc_opt_error(BC_ERR_FATAL_OPTION_ARG, o->optopt, name);
}
if (arg != NULL) o->optarg = arg;
@ -229,7 +231,7 @@ int bc_opt_parse(BcOpt *o, const BcOptLong *longopts) {
o->optarg = o->argv[o->optind];
if (o->optarg != NULL) o->optind += 1;
else bc_opt_error(BC_ERROR_FATAL_OPTION_NO_ARG,
else bc_opt_error(BC_ERR_FATAL_OPTION_NO_ARG,
o->optopt, name);
}
@ -237,7 +239,7 @@ int bc_opt_parse(BcOpt *o, const BcOptLong *longopts) {
}
}
bc_opt_error(BC_ERROR_FATAL_OPTION, 0, option);
bc_opt_error(BC_ERR_FATAL_OPTION, 0, option);
return -1;
}

View File

@ -40,9 +40,6 @@
#include <limits.h>
#include <status.h>
#include <vector.h>
#include <lex.h>
#include <parse.h>
#include <program.h>
#include <vm.h>

View File

@ -61,7 +61,7 @@ static inline void bc_program_type_num(BcResult *r, BcNum *n) {
assert(r->t != BC_RESULT_VOID);
#endif // BC_ENABLED
if (BC_ERR(!BC_PROG_NUM(r, n))) bc_vm_err(BC_ERROR_EXEC_TYPE);
if (BC_ERR(!BC_PROG_NUM(r, n))) bc_vm_err(BC_ERR_EXEC_TYPE);
}
#if BC_ENABLED
@ -72,7 +72,7 @@ static void bc_program_type_match(BcResult *r, BcType t) {
#endif // DC_ENABLED
if (BC_ERR((r->t != BC_RESULT_ARRAY) != (!t)))
bc_vm_err(BC_ERROR_EXEC_TYPE);
bc_vm_err(BC_ERR_EXEC_TYPE);
}
#endif // BC_ENABLED
@ -270,7 +270,7 @@ static void bc_program_operand(BcProgram *p, BcResult **r,
*r = bc_vec_item_rev(&p->results, idx);
#if BC_ENABLED
if (BC_ERR((*r)->t == BC_RESULT_VOID)) bc_vm_err(BC_ERROR_EXEC_VOID_VAL);
if (BC_ERR((*r)->t == BC_RESULT_VOID)) bc_vm_err(BC_ERR_EXEC_VOID_VAL);
#endif // BC_ENABLED
*n = bc_program_num(p, *r);
@ -286,7 +286,7 @@ static void bc_program_binPrep(BcProgram *p, BcResult **l, BcNum **ln,
#ifndef BC_PROG_NO_STACK_CHECK
if (BC_IS_DC) {
if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 2)))
bc_vm_err(BC_ERROR_EXEC_STACK);
bc_vm_err(BC_ERR_EXEC_STACK);
}
#endif // BC_PROG_NO_STACK_CHECK
@ -306,7 +306,7 @@ static void bc_program_binPrep(BcProgram *p, BcResult **l, BcNum **ln,
if (lt == (*r)->t && (lt == BC_RESULT_VAR || lt == BC_RESULT_ARRAY_ELEM))
*ln = bc_program_num(p, *l);
if (BC_ERR(lt == BC_RESULT_STR)) bc_vm_err(BC_ERROR_EXEC_TYPE);
if (BC_ERR(lt == BC_RESULT_STR)) bc_vm_err(BC_ERR_EXEC_TYPE);
}
static void bc_program_binOpPrep(BcProgram *p, BcResult **l, BcNum **ln,
@ -329,7 +329,7 @@ static void bc_program_assignPrep(BcProgram *p, BcResult **l, BcNum **ln,
lt = (*l)->t;
if (BC_ERR(lt >= min && lt <= BC_RESULT_ONE))
bc_vm_err(BC_ERROR_EXEC_TYPE);
bc_vm_err(BC_ERR_EXEC_TYPE);
#if DC_ENABLED
if(BC_IS_DC) {
@ -351,7 +351,7 @@ static void bc_program_prep(BcProgram *p, BcResult **r, BcNum **n, size_t idx) {
#ifndef BC_PROG_NO_STACK_CHECK
if (BC_IS_DC) {
if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1)))
bc_vm_err(BC_ERROR_EXEC_STACK);
bc_vm_err(BC_ERR_EXEC_STACK);
}
#endif // BC_PROG_NO_STACK_CHECK
@ -391,7 +391,7 @@ static void bc_program_const(BcProgram *p, const char *code, size_t *bgn) {
}
// bc_num_parse() should only do operations that cannot fail.
bc_num_parse(&c->num, c->val, base, !c->val[1]);
bc_num_parse(&c->num, c->val, base);
c->base = base;
}
@ -419,6 +419,9 @@ static void bc_program_op(BcProgram *p, uchar inst) {
BC_SIG_UNLOCK;
assert(BC_NUM_RDX_VALID(n1));
assert(BC_NUM_RDX_VALID(n2));
bc_program_ops[idx](n1, n2, &res->d.n, BC_PROG_SCALE(p));
bc_program_retire(p, 1, 2);
@ -437,7 +440,7 @@ static void bc_program_read(BcProgram *p) {
for (i = 0; i < p->stack.len; ++i) {
BcInstPtr *ip_ptr = bc_vec_item(&p->stack, i);
if (ip_ptr->func == BC_PROG_READ)
bc_vm_err(BC_ERROR_EXEC_REC_READ);
bc_vm_err(BC_ERR_EXEC_REC_READ);
}
BC_SIG_LOCK;
@ -454,13 +457,13 @@ static void bc_program_read(BcProgram *p) {
bc_vec_npop(&f->code, f->code.len);
s = bc_read_line(&buf, BC_IS_BC ? "read> " : "?> ");
if (s == BC_STATUS_EOF) bc_vm_err(BC_ERROR_EXEC_READ_EXPR);
if (s == BC_STATUS_EOF) bc_vm_err(BC_ERR_EXEC_READ_EXPR);
bc_parse_text(&parse, buf.v);
vm.expr(&parse, BC_PARSE_NOREAD | BC_PARSE_NEEDVAL);
if (BC_ERR(parse.l.t != BC_LEX_NLINE && parse.l.t != BC_LEX_EOF))
bc_vm_err(BC_ERROR_EXEC_READ_EXPR);
bc_vm_err(BC_ERR_EXEC_READ_EXPR);
#if BC_ENABLED
if (BC_G) bc_program_prepGlobals(p);
@ -495,6 +498,12 @@ exec_err:
static void bc_program_rand(BcProgram *p) {
BcRand rand = bc_rand_int(&p->rng);
bc_program_pushBigdig(p, (BcBigDig) rand, BC_RESULT_TEMP);
#ifndef NDEBUG
{
BcResult *r = bc_vec_top(&p->results);
assert(BC_NUM_RDX_VALID_NP(r->d.n));
}
#endif // NDEBUG
}
#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
@ -560,7 +569,7 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) {
#ifndef BC_PROG_NO_STACK_CHECK
if (BC_IS_DC) {
if (BC_ERR(!BC_PROG_STACK(&p->results, idx + 1)))
bc_vm_err(BC_ERROR_EXEC_STACK);
bc_vm_err(BC_ERR_EXEC_STACK);
}
#endif // BC_PROG_NO_STACK_CHECK
@ -570,7 +579,7 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) {
#if BC_ENABLED
if (r->t == BC_RESULT_VOID) {
if (BC_ERR(pop)) bc_vm_err(BC_ERROR_EXEC_VOID_VAL);
if (BC_ERR(pop)) bc_vm_err(BC_ERR_EXEC_VOID_VAL);
bc_vec_pop(&p->results);
return;
}
@ -604,7 +613,7 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) {
void bc_program_negate(BcResult *r, BcNum *n) {
bc_num_copy(&r->d.n, n);
if (BC_NUM_NONZERO(&r->d.n)) r->d.n.neg = !r->d.n.neg;
if (BC_NUM_NONZERO(&r->d.n)) BC_NUM_NEG_TGL_NP(r->d.n);
}
void bc_program_not(BcResult *r, BcNum *n) {
@ -743,7 +752,7 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx,
if (BC_IS_DC) {
if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
bc_vm_err(BC_ERROR_EXEC_STACK);
bc_vm_err(BC_ERR_EXEC_STACK);
assert(BC_PROG_STACK(&p->results, 1));
@ -768,7 +777,7 @@ static void bc_program_copyToVar(BcProgram *p, size_t idx,
#if DC_ENABLED
if (BC_IS_DC && (ptr->t == BC_RESULT_STR || BC_PROG_STR(n))) {
if (BC_ERR(!var)) bc_vm_err(BC_ERROR_EXEC_TYPE);
if (BC_ERR(!var)) bc_vm_err(BC_ERR_EXEC_TYPE);
bc_program_assignStr(p, ptr, vec, true);
return;
}
@ -871,6 +880,9 @@ static void bc_program_assign(BcProgram *p, uchar inst) {
if (!use_val)
inst -= (BC_INST_ASSIGN_POWER_NO_VAL - BC_INST_ASSIGN_POWER);
assert(BC_NUM_RDX_VALID(l));
assert(BC_NUM_RDX_VALID(r));
bc_program_ops[inst - BC_INST_ASSIGN_POWER](l, r, l, scale);
}
#endif // BC_ENABLED
@ -882,10 +894,10 @@ static void bc_program_assign(BcProgram *p, uchar inst) {
BcVec *v;
BcBigDig *ptr, *ptr_t, val, max, min;
BcError e;
BcErr e;
bc_num_bigdig(l, &val);
e = left->t - BC_RESULT_IBASE + BC_ERROR_EXEC_IBASE;
e = left->t - BC_RESULT_IBASE + BC_ERR_EXEC_IBASE;
if (sc) {
min = 0;
@ -940,7 +952,7 @@ static void bc_program_pushVar(BcProgram *p, const char *restrict code,
BcVec *v = bc_program_vec(p, idx, BC_TYPE_VAR);
BcNum *num = bc_vec_top(v);
if (BC_ERR(!BC_PROG_STACK(v, 2 - copy))) bc_vm_err(BC_ERROR_EXEC_STACK);
if (BC_ERR(!BC_PROG_STACK(v, 2 - copy))) bc_vm_err(BC_ERR_EXEC_STACK);
assert(BC_PROG_STACK(v, 2 - copy));
@ -1058,9 +1070,9 @@ static void bc_program_call(BcProgram *p, const char *restrict code,
ip.func = bc_program_index(code, idx);
f = bc_vec_item(&p->fns, ip.func);
if (BC_ERR(!f->code.len)) bc_vm_verr(BC_ERROR_EXEC_UNDEF_FUNC, f->name);
if (BC_ERR(!f->code.len)) bc_vm_verr(BC_ERR_EXEC_UNDEF_FUNC, f->name);
if (BC_ERR(nparams != f->nparams))
bc_vm_verr(BC_ERROR_EXEC_PARAMS, f->nparams, nparams);
bc_vm_verr(BC_ERR_EXEC_PARAMS, f->nparams, nparams);
ip.len = p->results.len - nparams;
assert(BC_PROG_STACK(&p->results, nparams));
@ -1073,8 +1085,7 @@ static void bc_program_call(BcProgram *p, const char *restrict code,
bool last = true;
arg = bc_vec_top(&p->results);
if (BC_ERR(arg->t == BC_RESULT_VOID))
bc_vm_err(BC_ERROR_EXEC_VOID_VAL);
if (BC_ERR(arg->t == BC_RESULT_VOID)) bc_vm_err(BC_ERR_EXEC_VOID_VAL);
a = bc_vec_item(&f->autos, nparams - 1 - i);
@ -1178,7 +1189,7 @@ static void bc_program_builtin(BcProgram *p, uchar inst) {
#ifndef BC_PROG_NO_STACK_CHECK
if (BC_IS_DC) {
if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
bc_vm_err(BC_ERROR_EXEC_STACK);
bc_vm_err(BC_ERR_EXEC_STACK);
}
#endif // BC_PROG_NO_STACK_CHECK
@ -1203,7 +1214,7 @@ static void bc_program_builtin(BcProgram *p, uchar inst) {
BC_SIG_UNLOCK;
res->d.n.neg = false;
BC_NUM_NEG_CLR_NP(res->d.n);
}
#if BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
else if (inst == BC_INST_IRAND) {
@ -1271,7 +1282,7 @@ static void bc_program_divmod(BcProgram *p) {
BcNum *n1, *n2;
size_t req;
bc_vec_expand(&p->results, p->results.len + 2);
bc_vec_grow(&p->results, 2);
// We don't need to update the pointer because
// the capacity is enough due to the line above.
@ -1299,7 +1310,7 @@ static void bc_program_modexp(BcProgram *p) {
BcResult *r1, *r2, *r3, *res;
BcNum *n1, *n2, *n3;
if (BC_ERR(!BC_PROG_STACK(&p->results, 3))) bc_vm_err(BC_ERROR_EXEC_STACK);
if (BC_ERR(!BC_PROG_STACK(&p->results, 3))) bc_vm_err(BC_ERR_EXEC_STACK);
assert(BC_PROG_STACK(&p->results, 3));
@ -1346,7 +1357,7 @@ static uchar bc_program_asciifyNum(BcProgram *p, BcNum *n) {
BC_SIG_UNLOCK;
bc_num_truncate(&num, num.scale);
num.neg = false;
BC_NUM_NEG_CLR_NP(num);
// This is guaranteed to not have a divide by 0
// because strmb is equal to UCHAR_MAX + 1.
@ -1372,7 +1383,7 @@ static void bc_program_asciify(BcProgram *p) {
uchar c;
size_t idx;
if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERROR_EXEC_STACK);
if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERR_EXEC_STACK);
assert(BC_PROG_STACK(&p->results, 1));
@ -1409,7 +1420,7 @@ static void bc_program_printStream(BcProgram *p) {
BcResult *r;
BcNum *n;
if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERROR_EXEC_STACK);
if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERR_EXEC_STACK);
assert(BC_PROG_STACK(&p->results, 1));
@ -1471,7 +1482,7 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code,
assert(p->stack.len == p->tail_calls.len);
if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERROR_EXEC_STACK);
if (BC_ERR(!BC_PROG_STACK(&p->results, 1))) bc_vm_err(BC_ERR_EXEC_STACK);
assert(BC_PROG_STACK(&p->results, 1));
@ -1496,7 +1507,7 @@ static void bc_program_execStr(BcProgram *p, const char *restrict code,
n = bc_vec_top(bc_program_vec(p, idx, BC_TYPE_VAR));
else goto exit;
if (BC_ERR(!BC_PROG_STR(n))) bc_vm_err(BC_ERROR_EXEC_TYPE);
if (BC_ERR(!BC_PROG_STR(n))) bc_vm_err(BC_ERR_EXEC_TYPE);
BC_UNSETJMP;
BC_SIG_UNLOCK;
@ -1832,6 +1843,8 @@ void bc_program_exec(BcProgram *p) {
bc_vec_pop(&p->results);
}
// Fallthrough.
BC_FALLTHROUGH
case BC_INST_JUMP:
{
idx = bc_program_index(code, &ip->idx);
@ -2077,7 +2090,7 @@ void bc_program_exec(BcProgram *p) {
#ifndef BC_PROG_NO_STACK_CHECK
if (!BC_IS_BC) {
if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
bc_vm_err(BC_ERROR_EXEC_STACK);
bc_vm_err(BC_ERR_EXEC_STACK);
}
#endif // BC_PROG_NO_STACK_CHECK
@ -2145,7 +2158,7 @@ void bc_program_exec(BcProgram *p) {
case BC_INST_DUPLICATE:
{
if (BC_ERR(!BC_PROG_STACK(&p->results, 1)))
bc_vm_err(BC_ERROR_EXEC_STACK);
bc_vm_err(BC_ERR_EXEC_STACK);
assert(BC_PROG_STACK(&p->results, 1));
@ -2166,7 +2179,7 @@ void bc_program_exec(BcProgram *p) {
BcResult *ptr2;
if (BC_ERR(!BC_PROG_STACK(&p->results, 2)))
bc_vm_err(BC_ERROR_EXEC_STACK);
bc_vm_err(BC_ERR_EXEC_STACK);
assert(BC_PROG_STACK(&p->results, 2));

View File

@ -143,7 +143,7 @@ BcStatus bc_read_chars(BcVec *vec, const char *prompt) {
BC_SIG_UNLOCK;
bc_vm_err(BC_ERROR_FATAL_IO_ERR);
bc_vm_err(BC_ERR_FATAL_IO_ERR);
}
BC_SIG_UNLOCK;
@ -177,14 +177,14 @@ BcStatus bc_read_line(BcVec *vec, const char *prompt) {
#endif // BC_ENABLE_HISTORY
if (BC_ERR(bc_read_binary(vec->v, vec->len - 1)))
bc_vm_verr(BC_ERROR_FATAL_BIN_FILE, bc_program_stdin_name);
bc_vm_verr(BC_ERR_FATAL_BIN_FILE, bc_program_stdin_name);
return s;
}
void bc_read_file(const char *path, char **buf) {
BcError e = BC_ERROR_FATAL_IO_ERR;
BcErr e = BC_ERR_FATAL_IO_ERR;
size_t size, r;
struct stat pstat;
int fd;
@ -194,11 +194,11 @@ void bc_read_file(const char *path, char **buf) {
assert(path != NULL);
fd = open(path, O_RDONLY);
if (BC_ERR(fd < 0)) bc_vm_verr(BC_ERROR_FATAL_FILE_ERR, path);
if (BC_ERR(fd < 0)) bc_vm_verr(BC_ERR_FATAL_FILE_ERR, path);
if (BC_ERR(fstat(fd, &pstat) == -1)) goto malloc_err;
if (BC_ERR(S_ISDIR(pstat.st_mode))) {
e = BC_ERROR_FATAL_PATH_DIR;
e = BC_ERR_FATAL_PATH_DIR;
goto malloc_err;
}
@ -211,7 +211,7 @@ void bc_read_file(const char *path, char **buf) {
(*buf)[size] = '\0';
if (BC_ERR(bc_read_binary(*buf, size))) {
e = BC_ERROR_FATAL_BIN_FILE;
e = BC_ERR_FATAL_BIN_FILE;
goto read_err;
}

View File

@ -37,12 +37,11 @@
#include <stdlib.h>
#include <string.h>
#include <status.h>
#include <vector.h>
#include <lang.h>
#include <vm.h>
static void bc_vec_grow(BcVec *restrict v, size_t n) {
void bc_vec_grow(BcVec *restrict v, size_t n) {
size_t len, cap = v->cap;
sig_atomic_t lock;

126
src/vm.c
View File

@ -56,13 +56,15 @@
#endif // _WIN32
#include <status.h>
#include <vector.h>
#include <args.h>
#include <vm.h>
#include <read.h>
#include <bc.h>
char output_bufs[BC_VM_BUF_SIZE];
BcVm vm;
#if BC_DEBUG_CODE
BC_NORETURN void bc_vm_jmp(const char* f) {
#else // BC_DEBUG_CODE
@ -84,12 +86,14 @@ BC_NORETURN void bc_vm_jmp(void) {
assert(vm.jmp_bufs.len - (size_t) vm.sig_pop);
#endif // NDEBUG
if (vm.jmp_bufs.len == 0) abort();
if (vm.sig_pop) bc_vec_pop(&vm.jmp_bufs);
else vm.sig_pop = 1;
siglongjmp(*((sigjmp_buf*) bc_vec_top(&vm.jmp_bufs)), 1);
}
#if !BC_ENABLE_LIBRARY
static void bc_vm_sig(int sig) {
// There is already a signal in flight.
@ -132,8 +136,28 @@ void bc_vm_info(const char* const help) {
bc_file_flush(&vm.fout);
}
#endif // !BC_ENABLE_LIBRARY
void bc_vm_error(BcError e, size_t line, ...) {
#if BC_ENABLE_LIBRARY
void bc_vm_handleError(BcErr e) {
assert(e < BC_ERR_NELEMS);
assert(!vm.sig_pop);
BC_SIG_LOCK;
if (e <= BC_ERR_MATH_DIVIDE_BY_ZERO) {
vm.err = (BclError) (e - BC_ERR_MATH_NEGATIVE +
BCL_ERROR_MATH_NEGATIVE);
}
else if (vm.abrt) abort();
else if (e == BC_ERR_FATAL_ALLOC_ERR) vm.err = BCL_ERROR_FATAL_ALLOC_ERR;
else vm.err = BCL_ERROR_FATAL_UNKNOWN_ERR;
BC_VM_JMP;
}
#else // BC_ENABLE_LIBRARY
void bc_vm_handleError(BcErr e, size_t line, ...) {
BcStatus s;
va_list args;
@ -141,11 +165,11 @@ void bc_vm_error(BcError e, size_t line, ...) {
const char* err_type = vm.err_ids[id];
sig_atomic_t lock;
assert(e < BC_ERROR_NELEMS);
assert(e < BC_ERR_NELEMS);
assert(!vm.sig_pop);
#if BC_ENABLED
if (!BC_S && e >= BC_ERROR_POSIX_START) {
if (!BC_S && e >= BC_ERR_POSIX_START) {
if (BC_W) {
// Make sure to not return an error.
id = UCHAR_MAX;
@ -261,7 +285,7 @@ static void bc_vm_envArgs(const char* const env_args_name) {
buf += 1;
start = buf;
}
else if (instr) bc_vm_error(BC_ERROR_FATAL_OPTION, 0, start);
else if (instr) bc_vm_error(BC_ERR_FATAL_OPTION, 0, start);
}
else buf += 1;
}
@ -293,6 +317,7 @@ static size_t bc_vm_envLen(const char *var) {
return len;
}
#endif // BC_ENABLE_LIBRARY
void bc_vm_shutdown(void) {
@ -308,6 +333,7 @@ void bc_vm_shutdown(void) {
#endif // BC_ENABLE_HISTORY
#ifndef NDEBUG
#if !BC_ENABLE_LIBRARY
bc_vec_free(&vm.env_args);
free(vm.env_args_buffer);
bc_vec_free(&vm.files);
@ -315,31 +341,40 @@ void bc_vm_shutdown(void) {
bc_program_free(&vm.prog);
bc_parse_free(&vm.prs);
#endif // !BC_ENABLE_LIBRARY
{
size_t i;
for (i = 0; i < vm.temps.len; ++i)
free(((BcNum*) bc_vec_item(&vm.temps, i))->num);
bc_vec_free(&vm.temps);
}
bc_vm_freeTemps();
bc_vec_free(&vm.temps);
#endif // NDEBUG
#if !BC_ENABLE_LIBRARY
bc_file_free(&vm.fout);
bc_file_free(&vm.ferr);
#endif // !BC_ENABLE_LIBRARY
}
#if !defined(NDEBUG) || BC_ENABLE_LIBRARY
void bc_vm_freeTemps(void) {
size_t i;
for (i = 0; i < vm.temps.len; ++i) {
free(((BcNum*) bc_vec_item(&vm.temps, i))->num);
}
}
#endif // !defined(NDEBUG) || BC_ENABLE_LIBRARY
inline size_t bc_vm_arraySize(size_t n, size_t size) {
size_t res = n * size;
if (BC_ERR(res >= SIZE_MAX || (n != 0 && res / n != size)))
bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR);
bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
return res;
}
inline size_t bc_vm_growSize(size_t a, size_t b) {
size_t res = a + b;
if (BC_ERR(res >= SIZE_MAX || res < a || res < b))
bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR);
bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
return res;
}
@ -351,7 +386,7 @@ void* bc_vm_malloc(size_t n) {
ptr = malloc(n);
if (BC_ERR(ptr == NULL)) bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR);
if (BC_ERR(ptr == NULL)) bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
return ptr;
}
@ -364,7 +399,7 @@ void* bc_vm_realloc(void *ptr, size_t n) {
temp = realloc(ptr, n);
if (BC_ERR(temp == NULL)) bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR);
if (BC_ERR(temp == NULL)) bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
return temp;
}
@ -377,11 +412,12 @@ char* bc_vm_strdup(const char *str) {
s = strdup(str);
if (BC_ERR(!s)) bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR);
if (BC_ERR(!s)) bc_vm_err(BC_ERR_FATAL_ALLOC_ERR);
return s;
}
#if !BC_ENABLE_LIBRARY
void bc_vm_printf(const char *fmt, ...) {
va_list args;
@ -396,12 +432,18 @@ void bc_vm_printf(const char *fmt, ...) {
BC_SIG_UNLOCK;
}
#endif // !BC_ENABLE_LIBRARY
void bc_vm_putchar(int c) {
#if BC_ENABLE_LIBRARY
bc_vec_pushByte(&vm.out, (uchar) c);
#else // BC_ENABLE_LIBRARY
bc_file_putchar(&vm.fout, (uchar) c);
vm.nchars = (c == '\n' ? 0 : vm.nchars + 1);
#endif // BC_ENABLE_LIBRARY
}
#if !BC_ENABLE_LIBRARY
static void bc_vm_clean(void) {
BcVec *fns = &vm.prog.fns;
@ -491,7 +533,7 @@ static void bc_vm_endif(void) {
if (good) {
while (BC_PARSE_IF_END(&vm.prs)) bc_vm_process("else {}");
}
else bc_parse_err(&vm.prs, BC_ERROR_PARSE_BLOCK);
else bc_parse_err(&vm.prs, BC_ERR_PARSE_BLOCK);
}
#endif // BC_ENABLED
@ -604,9 +646,9 @@ restart:
if (!BC_STATUS_IS_ERROR(s)) {
if (BC_ERR(comment))
bc_parse_err(&vm.prs, BC_ERROR_PARSE_COMMENT);
bc_parse_err(&vm.prs, BC_ERR_PARSE_COMMENT);
else if (BC_ERR(string))
bc_parse_err(&vm.prs, BC_ERROR_PARSE_STRING);
bc_parse_err(&vm.prs, BC_ERR_PARSE_STRING);
#if BC_ENABLED
else if (BC_IS_BC) bc_vm_endif();
#endif // BC_ENABLED
@ -652,7 +694,7 @@ static void bc_vm_defaultMsgs(void) {
for (i = 0; i < BC_ERR_IDX_NELEMS + BC_ENABLED; ++i)
vm.err_ids[i] = bc_errs[i];
for (i = 0; i < BC_ERROR_NELEMS; ++i) vm.err_msgs[i] = bc_err_msgs[i];
for (i = 0; i < BC_ERR_NELEMS; ++i) vm.err_msgs[i] = bc_err_msgs[i];
}
static void bc_vm_gettext(void) {
@ -683,7 +725,7 @@ static void bc_vm_gettext(void) {
i = 0;
id = bc_err_ids[i];
for (set = id + 3, msg = 1; i < BC_ERROR_NELEMS; ++i, ++msg) {
for (set = id + 3, msg = 1; i < BC_ERR_NELEMS; ++i, ++msg) {
if (id != bc_err_ids[i]) {
msg = 1;
@ -775,8 +817,8 @@ err:
#endif // NDEBUG
}
void bc_vm_boot(int argc, char *argv[], const char *env_len,
const char* const env_args)
void bc_vm_boot(int argc, char *argv[], const char *env_len,
const char* const env_args)
{
int ttyin, ttyout, ttyerr;
struct sigaction sa;
@ -803,10 +845,7 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len,
if (BC_TTY) sigaction(SIGHUP, &sa, NULL);
#endif // BC_ENABLE_HISTORY
memcpy(vm.max_num, bc_num_bigdigMax,
bc_num_bigdigMax_size * sizeof(BcDig));
bc_num_setup(&vm.max, vm.max_num, BC_NUM_BIGDIG_LOG10);
vm.max.len = bc_num_bigdigMax_size;
bc_vm_init();
vm.file = NULL;
@ -822,8 +861,6 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len,
bc_vec_clear(&vm.files);
bc_vec_clear(&vm.exprs);
bc_vec_init(&vm.temps, sizeof(BcNum), NULL);
bc_program_init(&vm.prog);
bc_parse_init(&vm.prs, &vm.prog, BC_PROG_MAIN);
@ -842,6 +879,27 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len,
if (BC_IS_POSIX) vm.flags &= ~(BC_FLAG_G);
#endif // BC_ENABLED
BC_SIG_UNLOCK;
bc_vm_exec();
}
#endif // !BC_ENABLE_LIBRARY
void bc_vm_init(void) {
BC_SIG_ASSERT_LOCKED;
memcpy(vm.max_num, bc_num_bigdigMax,
bc_num_bigdigMax_size * sizeof(BcDig));
memcpy(vm.max2_num, bc_num_bigdigMax2,
bc_num_bigdigMax2_size * sizeof(BcDig));
bc_num_setup(&vm.max, vm.max_num, BC_NUM_BIGDIG_LOG10);
bc_num_setup(&vm.max2, vm.max2_num, BC_NUM_BIGDIG_LOG10);
vm.max.len = bc_num_bigdigMax_size;
vm.max2.len = bc_num_bigdigMax2_size;
bc_vec_init(&vm.temps, sizeof(BcNum), NULL);
vm.maxes[BC_PROG_GLOBALS_IBASE] = BC_NUM_MAX_POSIX_IBASE;
vm.maxes[BC_PROG_GLOBALS_OBASE] = BC_MAX_OBASE;
vm.maxes[BC_PROG_GLOBALS_SCALE] = BC_MAX_SCALE;
@ -851,11 +909,11 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len,
#endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND
#if BC_ENABLED
#if !BC_ENABLE_LIBRARY
if (BC_IS_BC && !BC_IS_POSIX)
#endif // !BC_ENABLE_LIBRARY
{
vm.maxes[BC_PROG_GLOBALS_IBASE] = BC_NUM_MAX_IBASE;
}
#endif // BC_ENABLED
BC_SIG_UNLOCK;
bc_vm_exec();
}