diff --git a/Makefile.in b/Makefile.in index aab7f9b569e5..2b50476a79fe 100644 --- a/Makefile.in +++ b/Makefile.in @@ -29,8 +29,6 @@ # .POSIX: -VERSION = 3.3.4 - SRC = %%SRC%% OBJ = %%OBJ%% GCDA = %%GCDA%% @@ -128,6 +126,8 @@ MAIN_EXEC = $(EXEC_PREFIX)$(%%MAIN_EXEC%%)$(EXEC_SUFFIX) EXEC = $(%%EXEC%%) NLSPATH = %%NLSPATH%% +BC_BUILD_TYPE = %%BUILD_TYPE%% + BC_ENABLE_LIBRARY = %%LIBRARY%% BC_ENABLE_HISTORY = %%HISTORY%% @@ -158,7 +158,7 @@ TEST_STARS = "****************************************************************** BC_NUM_KARATSUBA_LEN = %%KARATSUBA_LEN%% CPPFLAGS1 = -D$(BC_ENABLED_NAME)=$(BC_ENABLED) -D$(DC_ENABLED_NAME)=$(DC_ENABLED) -CPPFLAGS2 = $(CPPFLAGS1) -I./include/ -DVERSION=$(VERSION) %%LONG_BIT_DEFINE%% +CPPFLAGS2 = $(CPPFLAGS1) -I./include/ -DBUILD_TYPE=$(BC_BUILD_TYPE) %%LONG_BIT_DEFINE%% CPPFLAGS3 = $(CPPFLAGS2) -DEXECPREFIX=$(EXEC_PREFIX) -DMAINEXEC=$(MAIN_EXEC) CPPFLAGS4 = $(CPPFLAGS3) -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 CPPFLAGS5 = $(CPPFLAGS4) -DBC_NUM_KARATSUBA_LEN=$(BC_NUM_KARATSUBA_LEN) @@ -322,9 +322,6 @@ coverage_output: coverage:%%COVERAGE_PREREQS%% -version: - @printf '%s' "$(VERSION)" - libcname: @printf '%s' "$(BC_LIB_C)" @@ -341,6 +338,7 @@ clean_gen: clean:%%CLEAN_PREREQS%% @printf 'Cleaning files...\n' + @$(RM) -f src/*.tmp gen/*.tmp @$(RM) -f $(OBJ) @$(RM) -f $(BC_EXEC) @$(RM) -f $(DC_EXEC) @@ -352,6 +350,7 @@ clean:%%CLEAN_PREREQS%% @$(RM) -f $(DC_HELP_C) $(DC_HELP_O) @$(RM) -fr $(BC_TEST_OUTPUTS) $(DC_TEST_OUTPUTS) @$(RM) -fr $(BC_FUZZ_OUTPUTS) $(DC_FUZZ_OUTPUTS) + @$(RM) -fr Debug/ Release/ clean_config: clean @printf 'Cleaning config...\n' diff --git a/NEWS.md b/NEWS.md index 3374ab57bc41..011cb9138912 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,30 @@ # News +## 4.0.0 + +This is a production release with many fixes, a new command-line option, and a +big surprise: + +* A bug was fixed in `dc`'s `P` command where the item on the stack was *not* + popped. +* Various bugs in the manuals have been fixed. +* A known bug was fixed where history did not interact well with prompts printed + by user code without newlines. +* A new command-line option, `-R` and `--no-read-prompt` was added to disable + just the prompt when using `read()` (`bc`) or `?` (`dc`). +* And finally, **official support for Windows was added**. + +The last item is why this is a major version bump. + +Currently, only one set of build options (extra math and prompt enabled, history +and NLS/locale support disabled, both calculators enabled) is supported on +Windows. However, both debug and release builds are supported. + +In addition, Windows builds are supported for the the library (`bcl`). + +For more details about how to build on Windows, see the [README][5] or the +[build manual][13]. + ## 3.3.4 This is a production release that fixes a small bug. diff --git a/README.md b/README.md index 6a37a8bfb8da..852c8956a73d 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,16 @@ This `bc` is Free and Open Source Software (FOSS). It is offered under the BSD ## Prerequisites -This `bc` only requires a C99-compatible compiler and a (mostly) POSIX -2008-compatible system with the XSI (X/Open System Interfaces) option group. +This `bc` only requires either: + +1. Windows 10 or later, or +2. A C99-compatible compiler and a (mostly) POSIX 2008-compatible system with + the XSI (X/Open System Interfaces) option group. Since POSIX 2008 with XSI requires the existence of a C99 compiler as `c99`, any POSIX and XSI-compatible system will have everything needed. -Systems that are known to work: +POSIX-compatible systems that are known to work: * Linux * FreeBSD @@ -41,17 +44,68 @@ Systems that are known to work: * AIX * HP-UX* (except for history) +In addition, there is compatibility code to make this `bc` work on Windows. + Please submit bug reports if this `bc` does not build out of the box on any -system besides Windows. +system. ## Build -This `bc` should build unmodified on any POSIX-compliant system. +### Windows + +There is no guarantee that this `bc` will work on any version of Windows earlier +than Windows 10 (I cannot test on earlier versions), but it is guaranteed to +work on Windows 10 at least. + +Also, if building with MSBuild, the MSBuild bundled with Visual Studio is +required. + +**Note**: Unlike the POSIX-compatible platforms, only one build configuration is +supported on Windows: extra math and prompt enabled, history and NLS (locale +support) disabled, with both calculators built. + +#### `bc` + +To build `bc`, you can open the `bc.sln` file in Visual Studio, select the +configuration, and build. + +You can also build using MSBuild with the following from the root directory: + +``` +msbuild -property:Configuration= bc.sln +``` + +where `` is either one of `Debug` or `Release`. + +#### `bcl` (Library) + +To build the library, you can open the `bcl.sln` file in Visual Studio, select +the configuration, and build. + +You can also build using MSBuild with the following from the root directory: + +``` +msbuild -property:Configuration= bcl.sln +``` + +where `` is either one of `Debug` or `Release`. + +### POSIX-Compatible Systems + +This `bc` should build unmodified on any POSIX-compliant system or on Windows +starting with Windows 10 (though earlier versions may work). For more complex build requirements than the ones below, see the [build manual][5]. -### Default +On POSIX-compatible systems, `bc` is built as `bin/bc` and `dc` is built as +`bin/dc` by default. On Windows, they are built as `Release/bc/bc.exe` and +`Release/bc/dc.exe`. + +**Note**: On Windows, `dc.exe` is just copied from `bc.exe`; it is not linked. +Patches are welcome for a way to do that. + +#### Default For the default build with optimization, use the following commands in the root directory: @@ -61,7 +115,7 @@ directory: make ``` -### One Calculator +#### One Calculator To only build `bc`, use the following commands: @@ -77,7 +131,7 @@ To only build `dc`, use the following commands: make ``` -### Debug +#### Debug For debug builds, use the following commands in the root directory: @@ -86,7 +140,7 @@ For debug builds, use the following commands in the root directory: make ``` -### Install +#### Install To install, use the following command: @@ -99,7 +153,7 @@ other locations, use the `PREFIX` environment variable when running `configure.sh` or pass the `--prefix=` option to `configure.sh`. See the [build manual][5], or run `./configure.sh --help`, for more details. -### Library +#### 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`: @@ -114,11 +168,12 @@ 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`. +The library is built as `bin/libbcl.a` on POSIX-compatible systems or as +`Release/bcl/bcl.lib` on Windows. -### Package and Distro Maintainers +#### Package and Distro Maintainers -#### Recommended Compiler +##### Recommended Compiler When I ran benchmarks with my `bc` compiled under `clang`, it performed much better than when compiled under `gcc`. I recommend compiling this `bc` with @@ -127,7 +182,7 @@ better than when compiled under `gcc`. I recommend compiling this `bc` with I also recommend building this `bc` with C11 if you can because `bc` will detect a C11 compiler and add `_Noreturn` to any relevant function(s). -#### Recommended Optimizations +##### Recommended Optimizations I wrote this `bc` with Separation of Concerns, which means that there are many small functions that could be inlined. However, they are often called across @@ -154,12 +209,12 @@ However, I recommend ***NOT*** using `-march=native`. Doing so will reduce this `bc`'s performance, at least when building with link-time optimization. See the [benchmarks][19] for more details. -#### Stripping Binaries +##### Stripping Binaries By default, non-debug binaries are stripped, but stripping can be disabled with the `-T` option to `configure.sh`. -#### Using This `bc` as an Alternative +##### Using This `bc` as an Alternative If this `bc` is packaged as an alternative to an already existing `bc` package, it is possible to rename it in the build to prevent name collision. To prepend @@ -181,7 +236,7 @@ allowed. **Note**: The suggested name (and package name) when `bc` is not available is `bc-gh`. -#### Karatsuba Number +##### Karatsuba Number Package and distro maintainers have one tool at their disposal to build this `bc` in the optimal configuration: `karatsuba.py`. @@ -217,6 +272,7 @@ translations will also be added as they are provided. This `bc` compares favorably to GNU `bc`. +* This `bc` builds natively on Windows. * It has more extensions, which make this `bc` more useful for scripting. * This `bc` is a bit more POSIX compliant. * It has a much less buggy parser. The GNU `bc` will give parse errors for what @@ -246,7 +302,9 @@ To see what algorithms this `bc` uses, see the [algorithms manual][7]. ## Locales -Currently, this `bc` only has support for English (and US English), French, +Currently, there is no locale support on Windows. + +Additionally, this `bc` only has support for English (and US English), French, German, Portuguese, Dutch, Polish, Russian, Japanese, and Chinese locales. Patches are welcome for translations; use the existing `*.msg` files in `locales/` as a starting point. @@ -276,7 +334,8 @@ Other projects based on this bc are: ## Language -This `bc` is written in pure ISO C99, using POSIX 2008 APIs. +This `bc` is written in pure ISO C99, using POSIX 2008 APIs with custom Windows +compatibility code. ## Commit Messages @@ -294,6 +353,13 @@ tarballs. Files: .gitignore The git ignore file (maintainer use only). + .gitattributes The git attributes file (maintainer use only). + bc.sln The Visual Studio solution file for bc. + bc.vcxproj The Visual Studio project file for bc. + bc.vcxproj.filters The Visual Studio filters file for bc. + bcl.sln The Visual Studio solution file for bcl. + bcl.vcxproj The Visual Studio project file for bcl. + bcl.vcxproj.filters The Visual Studio filters file for bcl. configure A symlink to configure.sh to make packaging easier. configure.sh The configure script. functions.sh A script with functions used by other scripts. @@ -304,7 +370,8 @@ Files: locale_install.sh A script to install locales, if desired. locale_uninstall.sh A script to uninstall locales. Makefile.in The Makefile template. - manpage.sh Script to generate man pages from markdown files. + manpage.sh Script to generate man pages from markdown files + (maintainer use only). NOTICE.md List of contributors and copyright owners. RELEASE.md A checklist for making a release (maintainer use only). release.sh A script to test for release (maintainer use only). diff --git a/bc.sln b/bc.sln new file mode 100644 index 000000000000..584b28d13bf6 --- /dev/null +++ b/bc.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31129.286 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bc", "bc.vcxproj", "{D5086CFE-052C-4742-B005-E05DB983BBA2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D5086CFE-052C-4742-B005-E05DB983BBA2}.Debug|x64.ActiveCfg = Debug|x64 + {D5086CFE-052C-4742-B005-E05DB983BBA2}.Debug|x64.Build.0 = Debug|x64 + {D5086CFE-052C-4742-B005-E05DB983BBA2}.Debug|x86.ActiveCfg = Debug|Win32 + {D5086CFE-052C-4742-B005-E05DB983BBA2}.Debug|x86.Build.0 = Debug|Win32 + {D5086CFE-052C-4742-B005-E05DB983BBA2}.Release|x64.ActiveCfg = Release|x64 + {D5086CFE-052C-4742-B005-E05DB983BBA2}.Release|x64.Build.0 = Release|x64 + {D5086CFE-052C-4742-B005-E05DB983BBA2}.Release|x86.ActiveCfg = Release|Win32 + {D5086CFE-052C-4742-B005-E05DB983BBA2}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7869B1FB-A7C4-4FCF-8B99-F696DB2765EC} + EndGlobalSection +EndGlobal diff --git a/bc.vcxproj b/bc.vcxproj new file mode 100644 index 000000000000..ba0a7f6f1dd6 --- /dev/null +++ b/bc.vcxproj @@ -0,0 +1,278 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {D5086CFE-052C-4742-B005-E05DB983BBA2} + Win32Proj + + + + Application + true + v142 + + + Application + false + v142 + + + Application + true + v142 + + + Application + false + v142 + + + + + + + + + + + + + + + + + + + + + Building strgen + CL /Fo:$(Configuration)\$(ProjectName)\ /Fe:$(Configuration)\$(ProjectName)\strgen.exe gen\strgen.c + gen\strgen.c + $(Configuration)\$(ProjectName)\strgen.exe + + + Generating $(Configuration)\$(ProjectName)/lib.c + START $(Configuration)\$(ProjectName)/strgen gen\lib.bc $(Configuration)\$(ProjectName)/lib.c bc_lib bc_lib_name BC_ENABLED 1 + $(Configuration)\$(ProjectName)\strgen.exe;gen\lib.bc + $(Configuration)\$(ProjectName)\lib.c + + + Generating $(Configuration)\$(ProjectName)/lib2.c + START $(Configuration)\$(ProjectName)/strgen gen\lib2.bc $(Configuration)\$(ProjectName)/lib2.c bc_lib2 bc_lib2_name BC_ENABLED 1 + $(Configuration)\$(ProjectName)\strgen.exe;gen\lib2.bc + $(Configuration)\$(ProjectName)\lib2.c + + + Generating $(Configuration)\$(ProjectName)/bc_help.c + START $(Configuration)\$(ProjectName)/strgen gen\bc_help.txt $(Configuration)\$(ProjectName)\bc_help.c bc_help "" BC_ENABLED + $(Configuration)\$(ProjectName)\strgen.exe;gen\bc_help.txt + $(Configuration)\$(ProjectName)\bc_help.c + + + Generating $(Configuration)\$(ProjectName)/dc_help.c + START $(Configuration)\$(ProjectName)/strgen gen\dc_help.txt $(Configuration)\$(ProjectName)\dc_help.c dc_help "" DC_ENABLED + $(Configuration)\$(ProjectName)\strgen.exe;gen\dc_help.txt + $(Configuration)\$(ProjectName)\dc_help.c + + + + ClCompile + + + + true + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + + + false + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + + + + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_ENABLE_PROMPT=1;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;EXECSUFFIX=.exe;BUILD_TYPE=HN + $(SolutionDir)\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + false + /W3 %(AdditionalOptions) + + + MachineX86 + true + Console + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;bcrypt.lib;ucrt.lib;%(AdditionalDependencies) + + + copy /b "$(SolutionDir)\$(Configuration)\$(ProjectName)\bc.exe" "$(SolutionDir)\$(Configuration)\$(ProjectName)\dc.exe" + + + Copying bc to dc... + + + + + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_ENABLE_PROMPT=1;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;EXECSUFFIX=.exe;BUILD_TYPE=HN + $(SolutionDir)\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + Level3 + ProgramDatabase + MaxSpeed + false + /W3 %(AdditionalOptions) + + + MachineX86 + false + Console + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;bcrypt.lib;ucrt.lib;%(AdditionalDependencies) + true + true + + + copy /b "$(SolutionDir)\$(Configuration)\$(ProjectName)\bc.exe" "$(SolutionDir)\$(Configuration)\$(ProjectName)\dc.exe" + + + Copying bc to dc... + + + + + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_ENABLE_PROMPT=1;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;EXECSUFFIX=.exe;BUILD_TYPE=HN + $(SolutionDir)\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + false + /W3 %(AdditionalOptions) + + + MachineX64 + true + Console + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;bcrypt.lib;ucrt.lib;%(AdditionalDependencies) + + + copy /b "$(SolutionDir)\$(Configuration)\$(ProjectName)\bc.exe" "$(SolutionDir)\$(Configuration)\$(ProjectName)\dc.exe" + + + Copying bc to dc... + + + + + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_ENABLE_PROMPT=1;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=0;EXECSUFFIX=.exe;BUILD_TYPE=HN + $(SolutionDir)\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + Level3 + ProgramDatabase + MaxSpeed + false + /W3 %(AdditionalOptions) + Default + + + MachineX64 + false + Console + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;bcrypt.lib;ucrt.lib;%(AdditionalDependencies) + + + copy /b "$(SolutionDir)\$(Configuration)\$(ProjectName)\bc.exe" "$(SolutionDir)\$(Configuration)\$(ProjectName)\dc.exe" + + + Copying bc to dc... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bc.vcxproj.filters b/bc.vcxproj.filters new file mode 100644 index 000000000000..bc72b60519e9 --- /dev/null +++ b/bc.vcxproj.filters @@ -0,0 +1,182 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + + + + + + + + + + + Resource Files + + + Resource Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/bcl.sln b/bcl.sln new file mode 100644 index 000000000000..77009a439db3 --- /dev/null +++ b/bcl.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31129.286 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bcl", "bcl.vcxproj", "{D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E}.Debug|x64.ActiveCfg = Debug|x64 + {D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E}.Debug|x64.Build.0 = Debug|x64 + {D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E}.Debug|x86.ActiveCfg = Debug|Win32 + {D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E}.Debug|x86.Build.0 = Debug|Win32 + {D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E}.Release|x64.ActiveCfg = Release|x64 + {D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E}.Release|x64.Build.0 = Release|x64 + {D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E}.Release|x86.ActiveCfg = Release|Win32 + {D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {591735E0-C314-4BFF-A595-E9999B49CB25} + EndGlobalSection +EndGlobal diff --git a/bcl.vcxproj b/bcl.vcxproj new file mode 100644 index 000000000000..933c4e93094c --- /dev/null +++ b/bcl.vcxproj @@ -0,0 +1,161 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {D2CC3DCF-7919-4DEF-839D-E9B897EC3E8E} + Win32Proj + 10.0 + + + + StaticLibrary + true + v142 + + + StaticLibrary + false + v142 + + + StaticLibrary + true + v142 + + + StaticLibrary + false + v142 + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + + + true + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)\$(Configuration)\$(ProjectName)\ + + + + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_ENABLE_PROMPT=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1 + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + $(SolutionDir)\include + + + MachineX86 + true + Windows + + + + + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_ENABLE_PROMPT=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1 + MultiThreadedDLL + Level3 + ProgramDatabase + $(SolutionDir)\include + + + MachineX86 + true + Windows + true + true + + + + + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_ENABLE_PROMPT=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1 + $(SolutionDir)\include + + + + + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);BC_ENABLED=1;DC_ENABLED=1;BC_ENABLE_EXTRA_MATH=1;BC_ENABLE_HISTORY=0;BC_ENABLE_NLS=0;BC_ENABLE_PROMPT=0;BC_DEBUG_CODE=0;BC_ENABLE_LIBRARY=1 + $(SolutionDir)\include + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bcl.vcxproj.filters b/bcl.vcxproj.filters new file mode 100644 index 000000000000..5d8a13ba25f7 --- /dev/null +++ b/bcl.vcxproj.filters @@ -0,0 +1,96 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/configure b/configure deleted file mode 120000 index bd7a56adb6f9..000000000000 --- a/configure +++ /dev/null @@ -1 +0,0 @@ -configure.sh \ No newline at end of file diff --git a/configure b/configure new file mode 100755 index 000000000000..af96564e7702 --- /dev/null +++ b/configure @@ -0,0 +1,1321 @@ +#! /bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause +# +# Copyright (c) 2018-2021 Gavin D. Howard and contributors. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +script="$0" +scriptdir=$(dirname "$script") +script=$(basename "$script") + +. "$scriptdir/functions.sh" + +cd "$scriptdir" + +usage() { + + if [ $# -gt 0 ]; then + + _usage_val=1 + + printf "%s\n\n" "$1" + + else + _usage_val=0 + fi + + printf 'usage:\n' + printf ' %s -h\n' "$script" + printf ' %s --help\n' "$script" + printf ' %s [-a|-bD|-dB|-c] [-CEfgGHlmMNPtTvz] [-O OPT_LEVEL] [-k KARATSUBA_LEN]\n' "$script" + printf ' %s \\\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\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' + printf ' -c, --coverage\n' + printf ' Generate test coverage code. Requires gcov and regcovr.\n' + printf ' It is an error if either "-b" ("-D") or "-d" ("-B") is specified.\n' + printf ' Requires a compiler that use gcc-compatible coverage options\n' + printf ' -C, --disable-clean\n' + printf ' Disable the clean that configure.sh does before configure.\n' + printf ' -d, --dc-only\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 ' are specified too.\n' + printf ' -E, --disable-extra-math\n' + printf ' Disable extra math. This includes: "$" operator (truncate to integer),\n' + printf ' "@" operator (set number of decimal places), and r(x, p) (rounding\n' + printf ' function). Additionally, this option disables the extra printing\n' + printf ' functions in the math library.\n' + printf ' -f, --force\n' + printf ' Force use of all enabled options, even if they do not work. This\n' + printf ' option is to allow the maintainer a way to test that certain options\n' + printf ' are not failing invisibly. (Development only.)' + printf ' -g, --debug\n' + printf ' Build in debug mode. Adds the "-g" flag, and if there are no\n' + printf ' other CFLAGS, and "-O" was not given, this also adds the "-O0"\n' + printf ' flag. If this flag is *not* given, "-DNDEBUG" is added to CPPFLAGS\n' + printf ' and a strip flag is added to the link stage.\n' + printf ' -G, --disable-generated-tests\n' + printf ' Disable generating tests. This is for platforms that do not have a\n' + printf ' GNU bc-compatible bc to generate tests.\n' + printf ' -h, --help\n' + printf ' Print this help message and exit.\n' + printf ' -H, --disable-history\n' + printf ' Disable history.\n' + printf ' -k KARATSUBA_LEN, --karatsuba-len KARATSUBA_LEN\n' + printf ' Set the karatsuba length to KARATSUBA_LEN (default is 64).\n' + printf ' It is an error if KARATSUBA_LEN is not a number or is less than 16.\n' + printf ' -l, --install-all-locales\n' + printf ' Installs all locales, regardless of how many are on the system. This\n' + printf ' option is useful for package maintainers who want to make sure that\n' + printf ' a package contains all of the locales that end users might need.\n' + printf ' -m, --enable-memcheck\n' + printf ' Enable memcheck mode, to ensure no memory leaks. For development only.\n' + printf ' -M, --disable-man-pages\n' + printf ' Disable installing manpages.\n' + printf ' -N, --disable-nls\n' + printf ' Disable POSIX locale (NLS) support.\n' + printf ' -O OPT_LEVEL, --opt OPT_LEVEL\n' + printf ' Set the optimization level. This can also be included in the CFLAGS,\n' + printf ' but it is provided, so maintainers can build optimized debug builds.\n' + printf ' This is passed through to the compiler, so it must be supported.\n' + printf ' -P, --disable-prompt\n' + printf ' Disables the prompt in the built bc. The prompt will never show up,\n' + printf ' or in other words, it will be permanently disabled and cannot be\n' + printf ' enabled.\n' + printf ' -t, --enable-test-timing\n' + printf ' Enable the timing of tests. This is for development only.\n' + printf ' -T, --disable-strip\n' + printf ' Disable stripping symbols from the compiled binary or binaries.\n' + printf ' Stripping symbols only happens when debug mode is off.\n' + printf ' -v, --enable-valgrind\n' + printf ' Enable a build appropriate for valgrind. For development only.\n' + printf ' -z, --enable-fuzz-mode\n' + printf ' Enable fuzzing mode. THIS IS FOR DEVELOPMENT ONLY.\n' + printf ' --prefix PREFIX\n' + printf ' The prefix to install to. Overrides "$PREFIX" if it exists.\n' + printf ' If PREFIX is "/usr", install path will be "/usr/bin".\n' + printf ' Default is "/usr/local".\n' + printf ' --bindir BINDIR\n' + printf ' The directory to install binaries 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' + printf ' --datadir DATADIR\n' + printf ' The location for data files. Overrides "$DATADIR" if it exists.\n' + printf ' Default is "$DATAROOTDIR".\n' + printf ' --mandir MANDIR\n' + printf ' The location to install manpages to. Overrides "$MANDIR" if it exists.\n' + printf ' Default is "$DATADIR/man".\n' + printf ' --man1dir MAN1DIR\n' + printf ' The location to install Section 1 manpages to. Overrides "$MAN1DIR" if\n' + printf ' it exists. Default is "$MANDIR/man1".\n' + printf ' --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' + printf ' CC C compiler. Must be compatible with POSIX c99. If there is a\n' + printf ' space in the basename of the compiler, the items after the\n' + printf ' first space are assumed to be compiler flags, and in that case,\n' + printf ' the flags are automatically moved into CFLAGS. Default is\n' + printf ' "c99".\n' + printf ' HOSTCC Host C compiler. Must be compatible with POSIX c99. If there is\n' + printf ' a space in the basename of the compiler, the items after the\n' + printf ' first space are assumed to be compiler flags, and in the case,\n' + printf ' the flags are automatically moved into HOSTCFLAGS. Default is\n' + printf ' "$CC".\n' + printf ' HOST_CC Same as HOSTCC. If HOSTCC also exists, it is used.\n' + printf ' CFLAGS C compiler flags.\n' + printf ' HOSTCFLAGS CFLAGS for HOSTCC. Default is "$CFLAGS".\n' + printf ' HOST_CFLAGS Same as HOST_CFLAGS. If HOST_CFLAGS also exists, it is used.\n' + printf ' CPPFLAGS C preprocessor flags. Default is "".\n' + printf ' LDFLAGS Linker flags. Default is "".\n' + printf ' PREFIX The prefix to install to. Default is "/usr/local".\n' + printf ' If PREFIX is "/usr", install path will be "/usr/bin".\n' + printf ' BINDIR The directory to install binaries 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' + printf ' more information). Default is "/usr/share/locale/%%L/%%N".\n' + printf ' EXECSUFFIX The suffix to append to the executable names, used to not\n' + printf ' interfere with other installed bc executables. Default is "".\n' + printf ' EXECPREFIX The prefix to append to the executable names, used to not\n' + printf ' interfere with other installed bc executables. Default is "".\n' + printf ' DESTDIR For package creation. Default is "". If it is empty when\n' + printf ' `%s` is run, it can also be passed to `make install`\n' "$script" + printf ' later as an environment variable. If both are specified,\n' + printf ' the one given to `%s` takes precedence.\n' "$script" + printf ' LONG_BIT The number of bits in a C `long` type. This is mostly for the\n' + printf ' embedded space since this `bc` uses `long`s internally for\n' + printf ' overflow checking. In C99, a `long` is required to be 32 bits.\n' + printf ' For most normal desktop systems, setting this is unnecessary,\n' + printf ' except that 32-bit platforms with 64-bit longs may want to set\n' + printf ' it to `32`. Default is the default of `LONG_BIT` for the target\n' + printf ' platform. Minimum allowed is `32`. It is a build time error if\n' + printf ' the specified value of `LONG_BIT` is greater than the default\n' + printf ' value of `LONG_BIT` for the target platform.\n' + printf ' GEN_HOST Whether to use `gen/strgen.c`, instead of `gen/strgen.sh`, to\n' + printf ' produce the C files that contain the help texts as well as the\n' + printf ' math libraries. By default, `gen/strgen.c` is used, compiled by\n' + printf ' "$HOSTCC" and run on the host machine. Using `gen/strgen.sh`\n' + printf ' removes the need to compile and run an executable on the host\n' + printf ' machine since `gen/strgen.sh` is a POSIX shell script. However,\n' + printf ' `gen/lib2.bc` is perilously close to 4095 characters, the max\n' + printf ' supported length of a string literal in C99 (and it could be\n' + printf ' added to in the future), and `gen/strgen.sh` generates a string\n' + printf ' literal instead of an array, as `gen/strgen.c` does. For most\n' + printf ' production-ready compilers, this limit probably is not\n' + printf ' enforced, but it could be. Both options are still available for\n' + printf ' this reason. If you are sure your compiler does not have the\n' + printf ' limit and do not want to compile and run a binary on the host\n' + printf ' machine, set this variable to "0". Any other value, or a\n' + printf ' non-existent value, will cause the build system to compile and\n' + printf ' run `gen/strgen.c`. Default is "".\n' + printf ' GEN_EMU Emulator to run string generator code under (leave empty if not\n' + printf ' necessary). This is not necessary when using `gen/strgen.sh`.\n' + printf ' Default is "".\n' + printf '\n' + printf 'WARNING: even though `configure.sh` supports both option types, short and\n' + printf 'long, it does not support handling both at the same time. Use only one type.\n' + + exit "$_usage_val" +} + +replace_ext() { + + if [ "$#" -ne 3 ]; then + err_exit "Invalid number of args to $0" + fi + + _replace_ext_file="$1" + _replace_ext_ext1="$2" + _replace_ext_ext2="$3" + + _replace_ext_result="${_replace_ext_file%.$_replace_ext_ext1}.$_replace_ext_ext2" + + printf '%s\n' "$_replace_ext_result" +} + +replace_exts() { + + if [ "$#" -ne 3 ]; then + err_exit "Invalid number of args to $0" + fi + + _replace_exts_files="$1" + _replace_exts_ext1="$2" + _replace_exts_ext2="$3" + + for _replace_exts_file in $_replace_exts_files; do + _replace_exts_new_name=$(replace_ext "$_replace_exts_file" "$_replace_exts_ext1" "$_replace_exts_ext2") + _replace_exts_result="$_replace_exts_result $_replace_exts_new_name" + done + + printf '%s\n' "$_replace_exts_result" +} + +replace() { + + if [ "$#" -ne 3 ]; then + err_exit "Invalid number of args to $0" + fi + + _replace_str="$1" + _replace_needle="$2" + _replace_replacement="$3" + + substring_replace "$_replace_str" "%%$_replace_needle%%" "$_replace_replacement" +} + +find_src_files() { + + if [ "$#" -ge 1 ] && [ "$1" != "" ]; then + + while [ "$#" -ge 1 ]; do + _find_src_files_a="${1## }" + shift + _find_src_files_args="$_find_src_files_args ! -path src/${_find_src_files_a}" + done + + else + _find_src_files_args="-print" + fi + + printf '%s\n' $(find src/ -depth -name "*.c" $_find_src_files_args) +} + +gen_file_list() { + + if [ "$#" -lt 1 ]; then + err_exit "Invalid number of args to $0" + fi + + _gen_file_list_contents="$1" + shift + + p=$(pwd) + + cd "$scriptdir" + + if [ "$#" -ge 1 ]; then + _gen_file_list_unneeded="$@" + else + _gen_file_list_unneeded="" + fi + + _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_files $_gen_file_list_unneeded | 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" +} + +gen_tests() { + + _gen_tests_name="$1" + shift + + _gen_tests_uname="$1" + shift + + _gen_tests_extra_math="$1" + shift + + _gen_tests_time_tests="$1" + shift + + _gen_tests_extra_required=$(cat tests/extra_required.txt) + + for _gen_tests_t in $(cat "$scriptdir/tests/$_gen_tests_name/all.txt"); do + + if [ "$_gen_tests_extra_math" -eq 0 ]; then + + if [ -z "${_gen_tests_extra_required##*$_gen_tests_t*}" ]; then + printf 'test_%s_%s:\n\t@printf "Skipping %s %s\\n"\n\n' \ + "$_gen_tests_name" "$_gen_tests_t" "$_gen_tests_name" \ + "$_gen_tests_t" >> "$scriptdir/Makefile" + continue + fi + + fi + + printf 'test_%s_%s:\n\t@sh tests/test.sh %s %s %s %s %s\n\n' \ + "$_gen_tests_name" "$_gen_tests_t" "$_gen_tests_name" \ + "$_gen_tests_t" "$generate_tests" "$time_tests" \ + "$*" >> "$scriptdir/Makefile" + + done +} + +gen_test_targets() { + + _gen_test_targets_name="$1" + shift + + _gen_test_targets_tests=$(cat "$scriptdir/tests/${_gen_test_targets_name}/all.txt") + + for _gen_test_targets_t in $_gen_test_targets_tests; do + printf ' test_%s_%s' "$_gen_test_targets_name" "$_gen_test_targets_t" + done + + printf '\n' +} + +gen_script_tests() { + + _gen_script_tests_name="$1" + shift + + _gen_script_tests_extra_math="$1" + shift + + _gen_script_tests_generate="$1" + shift + + _gen_script_tests_time="$1" + shift + + _gen_script_tests_tests=$(cat "$scriptdir/tests/$_gen_script_tests_name/scripts/all.txt") + + for _gen_script_tests_f in $_gen_script_tests_tests; do + + _gen_script_tests_b=$(basename "$_gen_script_tests_f" ".${_gen_script_tests_name}") + + printf 'test_%s_script_%s:\n\t@sh tests/script.sh %s %s %s 1 %s %s %s\n\n' \ + "$_gen_script_tests_name" "$_gen_script_tests_b" "$_gen_script_tests_name" \ + "$_gen_script_tests_f" "$_gen_script_tests_extra_math" "$_gen_script_tests_generate" \ + "$_gen_script_tests_time" "$*" >> "$scriptdir/Makefile" + done +} + +gen_script_test_targets() { + + _gen_script_test_targets_name="$1" + shift + + _gen_script_test_targets_tests=$(cat "$scriptdir/tests/$_gen_script_test_targets_name/scripts/all.txt") + + for _gen_script_test_targets_f in $_gen_script_test_targets_tests; do + _gen_script_test_targets_b=$(basename "$_gen_script_test_targets_f" \ + ".$_gen_script_test_targets_name") + printf ' test_%s_script_%s' "$_gen_script_test_targets_name" \ + "$_gen_script_test_targets_b" + done + + printf '\n' +} + +bc_only=0 +dc_only=0 +coverage=0 +karatsuba_len=32 +debug=0 +hist=1 +extra_math=1 +optimization="" +generate_tests=1 +install_manpages=1 +nls=1 +prompt=1 +force=0 +strip_bin=1 +all_locales=0 +library=0 +fuzz=0 +time_tests=0 +vg=0 +memcheck=0 +clean=1 + +while getopts "abBcdDEfgGhHk:lMmNO:PStTvz-" opt; do + + case "$opt" in + a) library=1 ;; + b) bc_only=1 ;; + B) dc_only=1 ;; + c) coverage=1 ;; + C) clean=0 ;; + d) dc_only=1 ;; + D) bc_only=1 ;; + E) extra_math=0 ;; + f) force=1 ;; + g) debug=1 ;; + G) generate_tests=0 ;; + h) usage ;; + H) hist=0 ;; + k) karatsuba_len="$OPTARG" ;; + l) all_locales=1 ;; + m) memcheck=1 ;; + M) install_manpages=0 ;; + N) nls=0 ;; + O) optimization="$OPTARG" ;; + P) prompt=0 ;; + t) time_tests=1 ;; + T) strip_bin=0 ;; + v) vg=1 ;; + z) fuzz=1 ;; + -) + arg="$1" + arg="${arg#--}" + LONG_OPTARG="${arg#*=}" + case $arg in + help) usage ;; + library) library=1 ;; + bc-only) bc_only=1 ;; + dc-only) dc_only=1 ;; + coverage) coverage=1 ;; + debug) debug=1 ;; + force) force=1 ;; + prefix=?*) PREFIX="$LONG_OPTARG" ;; + prefix) + if [ "$#" -lt 2 ]; then + usage "No argument given for '--$arg' option" + fi + PREFIX="$2" + shift ;; + bindir=?*) BINDIR="$LONG_OPTARG" ;; + bindir) + if [ "$#" -lt 2 ]; then + usage "No argument given for '--$arg' option" + fi + BINDIR="$2" + shift ;; + 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 + usage "No argument given for '--$arg' option" + fi + DATAROOTDIR="$2" + shift ;; + datadir=?*) DATADIR="$LONG_OPTARG" ;; + datadir) + if [ "$#" -lt 2 ]; then + usage "No argument given for '--$arg' option" + fi + DATADIR="$2" + shift ;; + mandir=?*) MANDIR="$LONG_OPTARG" ;; + mandir) + if [ "$#" -lt 2 ]; then + usage "No argument given for '--$arg' option" + fi + MANDIR="$2" + shift ;; + man1dir=?*) MAN1DIR="$LONG_OPTARG" ;; + man1dir) + if [ "$#" -lt 2 ]; then + usage "No argument given for '--$arg' option" + fi + MAN1DIR="$2" + shift ;; + 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 + usage "No argument given for '--$arg' option" + fi + LOCALEDIR="$2" + shift ;; + karatsuba-len=?*) karatsuba_len="$LONG_OPTARG" ;; + karatsuba-len) + if [ "$#" -lt 2 ]; then + usage "No argument given for '--$arg' option" + fi + karatsuba_len="$1" + shift ;; + opt=?*) optimization="$LONG_OPTARG" ;; + opt) + if [ "$#" -lt 2 ]; then + usage "No argument given for '--$arg' option" + fi + optimization="$1" + shift ;; + disable-bc) dc_only=1 ;; + disable-dc) bc_only=1 ;; + disable-clean) clean=0 ;; + disable-extra-math) extra_math=0 ;; + disable-generated-tests) generate_tests=0 ;; + disable-history) hist=0 ;; + disable-man-pages) install_manpages=0 ;; + disable-nls) nls=0 ;; + disable-prompt) prompt=0 ;; + disable-strip) strip_bin=0 ;; + enable-test-timing) time_tests=1 ;; + enable-valgrind) vg=1 ;; + enable-fuzz-mode) fuzz=1 ;; + enable-memcheck) memcheck=1 ;; + install-all-locales) all_locales=1 ;; + help* | bc-only* | dc-only* | coverage* | debug*) + usage "No arg allowed for --$arg option" ;; + disable-bc* | disable-dc* | disable-clean*) + usage "No arg allowed for --$arg option" ;; + disable-extra-math*) + usage "No arg allowed for --$arg option" ;; + disable-generated-tests* | disable-history*) + usage "No arg allowed for --$arg option" ;; + disable-man-pages* | disable-nls* | disable-strip*) + usage "No arg allowed for --$arg option" ;; + enable-fuzz-mode* | enable-test-timing* | enable-valgrind*) + usage "No arg allowed for --$arg option" ;; + enable-memcheck* | install-all-locales*) + usage "No arg allowed for --$arg option" ;; + '') break ;; # "--" terminates argument processing + * ) usage "Invalid option $LONG_OPTARG" ;; + esac + shift + OPTIND=1 ;; + ?) usage "Invalid option $opt" ;; + esac + +done + +if [ "$clean" -ne 0 ]; then + if [ -f ./Makefile ]; then + make clean_config > /dev/null + fi +fi + +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" ;; + (*) ;; +esac + +if [ "$karatsuba_len" -lt 16 ]; then + usage "KARATSUBA_LEN is less than 16" +fi + +set -e + +if [ -z "${LONG_BIT+set}" ]; then + LONG_BIT_DEFINE="" +elif [ "$LONG_BIT" -lt 32 ]; then + usage "LONG_BIT is less than 32" +else + LONG_BIT_DEFINE="-DBC_LONG_BIT=\$(BC_LONG_BIT)" +fi + +if [ -z "$CC" ]; then + CC="c99" +else + ccbase=$(basename "$CC") + suffix=" *" + prefix="* " + + if [ "${ccbase%%$suffix}" != "$ccbase" ]; then + ccflags="${ccbase#$prefix}" + cc="${ccbase%%$suffix}" + ccdir=$(dirname "$CC") + if [ "$ccdir" = "." ] && [ "${CC#.}" = "$CC" ]; then + ccdir="" + else + ccdir="$ccdir/" + fi + CC="${ccdir}${cc}" + CFLAGS="$CFLAGS $ccflags" + fi +fi + +if [ -z "$HOSTCC" ] && [ -z "$HOST_CC" ]; then + HOSTCC="$CC" +elif [ -z "$HOSTCC" ]; then + HOSTCC="$HOST_CC" +fi + +if [ "$HOSTCC" != "$CC" ]; then + ccbase=$(basename "$HOSTCC") + suffix=" *" + prefix="* " + + if [ "${ccbase%%$suffix}" != "$ccbase" ]; then + ccflags="${ccbase#$prefix}" + cc="${ccbase%%$suffix}" + ccdir=$(dirname "$HOSTCC") + if [ "$ccdir" = "." ] && [ "${HOSTCC#.}" = "$HOSTCC" ]; then + ccdir="" + else + ccdir="$ccdir/" + fi + HOSTCC="${ccdir}${cc}" + HOSTCFLAGS="$HOSTCFLAGS $ccflags" + fi +fi + +if [ -z "${HOSTCFLAGS+set}" ] && [ -z "${HOST_CFLAGS+set}" ]; then + HOSTCFLAGS="$CFLAGS" +elif [ -z "${HOSTCFLAGS+set}" ]; then + HOSTCFLAGS="$HOST_CFLAGS" +fi + +link="@printf 'No link necessary\\\\n'" +main_exec="BC" +executable="BC_EXEC" + +tests="test_bc timeconst test_dc" + +bc_test="@tests/all.sh bc $extra_math 1 $generate_tests 0 \$(BC_EXEC)" +dc_test="@tests/all.sh dc $extra_math 1 $generate_tests 0 \$(DC_EXEC)" + +timeconst="@tests/bc/timeconst.sh tests/bc/scripts/timeconst.bc \$(BC_EXEC)" + +# In order to have cleanup at exit, we need to be in +# debug mode, so don't run valgrind without that. +if [ "$vg" -ne 0 ]; then + debug=1 + bc_test_exec='valgrind $(VALGRIND_ARGS) $(BC_EXEC)' + dc_test_exec='valgrind $(VALGRIND_ARGS) $(DC_EXEC)' +else + bc_test_exec='$(BC_EXEC)' + dc_test_exec='$(DC_EXEC)' +fi + +karatsuba="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'" +karatsuba_test="@printf 'karatsuba cannot be run because one of bc or dc is not built\\\\n'" + +bc_lib="\$(GEN_DIR)/lib.o" +bc_help="\$(GEN_DIR)/bc_help.o" +dc_help="\$(GEN_DIR)/dc_help.o" + +default_target_prereqs="\$(BIN) \$(OBJS)" +default_target_cmd="\$(CC) \$(CFLAGS) \$(OBJS) \$(LDFLAGS) -o \$(EXEC)" +default_target="\$(DC_EXEC)" + +second_target_prereqs="" +second_target_cmd="$default_target_cmd" +second_target="\$(BC_EXEC)" + +if [ "$library" -ne 0 ]; then + + extra_math=1 + nls=0 + hist=0 + prompt=0 + bc=1 + dc=1 + + default_target_prereqs="\$(BIN) \$(OBJ)" + default_target_cmd="ar -r -cu \$(LIBBC) \$(OBJ)" + default_target="\$(LIBBC)" + tests="test_library" + +elif [ "$bc_only" -eq 1 ]; then + + bc=1 + dc=0 + + dc_help="" + + executables="bc" + + dc_test="@printf 'No dc tests to run\\\\n'" + + install_prereqs=" install_execs" + install_man_prereqs=" install_bc_manpage" + uninstall_prereqs=" uninstall_bc" + uninstall_man_prereqs=" uninstall_bc_manpage" + + default_target="\$(BC_EXEC)" + second_target="\$(DC_EXEC)" + tests="test_bc timeconst" + +elif [ "$dc_only" -eq 1 ]; then + + bc=0 + dc=1 + + bc_lib="" + bc_help="" + + executables="dc" + + main_exec="DC" + executable="DC_EXEC" + + bc_test="@printf 'No bc tests to run\\\\n'" + + timeconst="@printf 'timeconst cannot be run because bc is not built\\\\n'" + + install_prereqs=" install_execs" + install_man_prereqs=" install_dc_manpage" + uninstall_prereqs=" uninstall_dc" + uninstall_man_prereqs=" uninstall_dc_manpage" + + tests="test_dc" + +else + + bc=1 + dc=1 + + executables="bc and dc" + + karatsuba="@\$(KARATSUBA) 30 0 \$(BC_EXEC)" + karatsuba_test="@\$(KARATSUBA) 1 100 \$(BC_EXEC)" + + 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 + + second_target_prereqs="$default_target_prereqs" + default_target_prereqs="$second_target" + default_target_cmd="\$(LINK) \$(BIN) \$(EXEC_PREFIX)\$(DC)" + +fi + +if [ "$fuzz" -ne 0 ]; then + debug=1 + hist=0 + prompt=0 + nls=0 + optimization="3" +fi + +if [ "$debug" -eq 1 ]; then + + if [ -z "$CFLAGS" ] && [ -z "$optimization" ]; then + CFLAGS="-O0" + fi + + CFLAGS="-g $CFLAGS" + +else + CPPFLAGS="-DNDEBUG $CPPFLAGS" + if [ "$strip_bin" -ne 0 ]; then + LDFLAGS="-s $LDFLAGS" + fi +fi + +if [ -n "$optimization" ]; then + CFLAGS="-O$optimization $CFLAGS" +fi + +if [ "$coverage" -eq 1 ]; then + + if [ "$bc_only" -eq 1 ] || [ "$dc_only" -eq 1 ]; then + usage "Can only specify -c without -b or -d" + fi + + CFLAGS="-fprofile-arcs -ftest-coverage -g -O0 $CFLAGS" + CPPFLAGS="-DNDEBUG $CPPFLAGS" + + COVERAGE_OUTPUT="@gcov -pabcdf \$(GCDA) \$(BC_GCDA) \$(DC_GCDA) \$(HISTORY_GCDA) \$(RAND_GCDA)" + COVERAGE_OUTPUT="$COVERAGE_OUTPUT;\$(RM) -f \$(GEN)*.gc*" + COVERAGE_OUTPUT="$COVERAGE_OUTPUT;gcovr --html-details --output index.html" + COVERAGE_PREREQS=" test coverage_output" + +else + COVERAGE_OUTPUT="@printf 'Coverage not generated\\\\n'" + COVERAGE_PREREQS="" +fi + +if [ -z "${DESTDIR+set}" ]; then + destdir="" +else + destdir="DESTDIR = $DESTDIR" +fi + +if [ -z "${PREFIX+set}" ]; then + PREFIX="/usr/local" +fi + +if [ -z "${BINDIR+set}" ]; then + BINDIR="$PREFIX/bin" +fi + +if [ -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" + fi +fi + +if [ "$install_manpages" -ne 0 ]; then + + if [ -z "${DATADIR+set}" ]; then + DATADIR="$DATAROOTDIR" + fi + + if [ -z "${MANDIR+set}" ]; then + MANDIR="$DATADIR/man" + fi + + if [ -z "${MAN1DIR+set}" ]; then + MAN1DIR="$MANDIR/man1" + fi + + if [ -z "${MAN3DIR+set}" ]; then + MAN3DIR="$MANDIR/man3" + fi + +else + install_man_prereqs="" + uninstall_man_prereqs="" +fi + +if [ "$nls" -ne 0 ]; then + + set +e + + printf 'Testing NLS...\n' + + flags="-DBC_ENABLE_NLS=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc" + flags="$flags -DBC_ENABLE_HISTORY=$hist" + flags="$flags -DBC_ENABLE_EXTRA_MATH=$extra_math -I./include/" + flags="$flags -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700" + + "$CC" $CPPFLAGS $CFLAGS $flags -c "src/vm.c" -o "$scriptdir/vm.o" > /dev/null 2>&1 + + err="$?" + + rm -rf "$scriptdir/vm.o" + + # If this errors, it is probably because of building on Windows, + # and NLS is not supported on Windows, so disable it. + if [ "$err" -ne 0 ]; then + printf 'NLS does not work.\n' + if [ $force -eq 0 ]; then + printf 'Disabling NLS...\n\n' + nls=0 + else + printf 'Forcing NLS...\n\n' + fi + else + printf 'NLS works.\n\n' + + printf 'Testing gencat...\n' + gencat "$scriptdir/en_US.cat" "$scriptdir/locales/en_US.msg" > /dev/null 2>&1 + + err="$?" + + rm -rf "$scriptdir/en_US.cat" + + if [ "$err" -ne 0 ]; then + printf 'gencat does not work.\n' + if [ $force -eq 0 ]; then + printf 'Disabling NLS...\n\n' + nls=0 + else + printf 'Forcing NLS...\n\n' + fi + else + + printf 'gencat works.\n\n' + + if [ "$HOSTCC" != "$CC" ]; then + printf 'Cross-compile detected.\n\n' + printf 'WARNING: Catalog files generated with gencat may not be portable\n' + printf ' across different architectures.\n\n' + fi + + if [ -z "$NLSPATH" ]; then + NLSPATH="/usr/share/locale/%L/%N" + fi + + install_locales_prereqs=" install_locales" + uninstall_locales_prereqs=" uninstall_locales" + + fi + + fi + + set -e + +else + install_locales_prereqs="" + uninstall_locales_prereqs="" + all_locales=0 +fi + +if [ "$nls" -ne 0 ] && [ "$all_locales" -ne 0 ]; then + install_locales="\$(LOCALE_INSTALL) -l \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)" +else + install_locales="\$(LOCALE_INSTALL) \$(NLSPATH) \$(MAIN_EXEC) \$(DESTDIR)" +fi + +if [ "$hist" -eq 1 ]; then + + set +e + + printf 'Testing history...\n' + + flags="-DBC_ENABLE_HISTORY=1 -DBC_ENABLED=$bc -DDC_ENABLED=$dc" + flags="$flags -DBC_ENABLE_NLS=$nls -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.c" -o "$scriptdir/history.o" > /dev/null 2>&1 + + err="$?" + + rm -rf "$scriptdir/history.o" + + # If this errors, it is probably because of building on Windows, + # and history is not supported on Windows, so disable it. + if [ "$err" -ne 0 ]; then + printf 'History does not work.\n' + if [ $force -eq 0 ]; then + printf 'Disabling history...\n\n' + hist=0 + else + printf 'Forcing history...\n\n' + fi + else + printf 'History works.\n\n' + fi + + set -e + +fi + +if [ "$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="" +fi + +GEN="strgen" +GEN_EXEC_TARGET="\$(HOSTCC) \$(HOSTCFLAGS) -o \$(GEN_EXEC) \$(GEN_C)" +CLEAN_PREREQS=" clean_gen" + +if [ -z "${GEN_HOST+set}" ]; then + GEN_HOST=1 +else + if [ "$GEN_HOST" -eq 0 ]; then + GEN="strgen.sh" + GEN_EXEC_TARGET="@printf 'Do not need to build gen/strgen.c\\\\n'" + CLEAN_PREREQS="" + fi +fi + +manpage_args="" +unneeded="" +headers="\$(HEADERS)" + +if [ "$extra_math" -eq 0 ]; then + manpage_args="E" + unneeded="$unneeded rand.c" +else + headers="$headers \$(EXTRA_MATH_HEADERS)" +fi + +if [ "$hist" -eq 0 ]; then + manpage_args="${manpage_args}H" + unneeded="$unneeded history.c" +else + headers="$headers \$(HISTORY_HEADERS)" +fi + +if [ "$nls" -eq 0 ]; then + manpage_args="${manpage_args}N" +fi + +if [ "$prompt" -eq 0 ]; then + manpage_args="${manpage_args}P" +fi + +if [ "$bc" -eq 0 ]; then + unneeded="$unneeded bc.c bc_lex.c bc_parse.c" +else + headers="$headers \$(BC_HEADERS)" +fi + +if [ "$dc" -eq 0 ]; then + unneeded="$unneeded dc.c dc_lex.c dc_parse.c" +else + headers="$headers \$(DC_HEADERS)" +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" + headers="$headers \$(LIBRARY_HEADERS)" +else + unneeded="$unneeded library.c" +fi + +if [ "$manpage_args" = "" ]; then + manpage_args="A" +fi + +if [ "$vg" -ne 0 ]; then + memcheck=1 +fi + +bc_tests=$(gen_test_targets bc) +bc_script_tests=$(gen_script_test_targets bc) +dc_tests=$(gen_test_targets dc) +dc_script_tests=$(gen_script_test_targets dc) + +# Print out the values; this is for debugging. +if [ "$bc" -ne 0 ]; then + printf 'Building bc\n' +else + printf 'Not building bc\n' +fi +if [ "$dc" -ne 0 ]; then + printf 'Building dc\n' +else + printf 'Not building dc\n' +fi +printf '\n' +printf 'BC_ENABLE_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" +printf 'BC_ENABLE_PROMPT=%s\n' "$prompt" +printf 'BC_ENABLE_AFL=%s\n' "$fuzz" +printf '\n' +printf 'BC_NUM_KARATSUBA_LEN=%s\n' "$karatsuba_len" +printf '\n' +printf 'CC=%s\n' "$CC" +printf 'CFLAGS=%s\n' "$CFLAGS" +printf 'HOSTCC=%s\n' "$HOSTCC" +printf 'HOSTCFLAGS=%s\n' "$HOSTCFLAGS" +printf 'CPPFLAGS=%s\n' "$CPPFLAGS" +printf 'LDFLAGS=%s\n' "$LDFLAGS" +printf 'PREFIX=%s\n' "$PREFIX" +printf 'BINDIR=%s\n' "$BINDIR" +printf '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" +printf 'DESTDIR=%s\n' "$DESTDIR" +printf 'LONG_BIT=%s\n' "$LONG_BIT" +printf 'GEN_HOST=%s\n' "$GEN_HOST" +printf 'GEN_EMU=%s\n' "$GEN_EMU" + +contents=$(cat "$scriptdir/Makefile.in") + +needle="WARNING" +replacement='*** WARNING: Autogenerated from Makefile.in. DO NOT MODIFY ***' + +contents=$(replace "$contents" "$needle" "$replacement") + +if [ "$unneeded" = "" ]; then + unneeded="library.c" +fi + +contents=$(gen_file_list "$contents" $unneeded) + +SRC_TARGETS="" + +src_files=$(find_src_files $unneeded) + +for f in $src_files; do + o=$(replace_ext "$f" "c" "o") + SRC_TARGETS=$(printf '%s\n\n%s: %s %s\n\t$(CC) $(CFLAGS) -o %s -c %s\n' \ + "$SRC_TARGETS" "$o" "$headers" "$f" "$o" "$f") +done + +contents=$(replace "$contents" "HEADERS" "$headers") + +contents=$(replace "$contents" "BC_ENABLED" "$bc") +contents=$(replace "$contents" "DC_ENABLED" "$dc") + +contents=$(replace "$contents" "BC_ALL_TESTS" "$bc_test") +contents=$(replace "$contents" "BC_TESTS" "$bc_tests") +contents=$(replace "$contents" "BC_SCRIPT_TESTS" "$bc_script_tests") +contents=$(replace "$contents" "BC_TEST_EXEC" "$bc_test_exec") +contents=$(replace "$contents" "TIMECONST_ALL_TESTS" "$timeconst") + +contents=$(replace "$contents" "DC_ALL_TESTS" "$dc_test") +contents=$(replace "$contents" "DC_TESTS" "$dc_tests") +contents=$(replace "$contents" "DC_SCRIPT_TESTS" "$dc_script_tests") +contents=$(replace "$contents" "DC_TEST_EXEC" "$dc_test_exec") + +contents=$(replace "$contents" "BUILD_TYPE" "$manpage_args") + +contents=$(replace "$contents" "LIBRARY" "$library") +contents=$(replace "$contents" "HISTORY" "$hist") +contents=$(replace "$contents" "EXTRA_MATH" "$extra_math") +contents=$(replace "$contents" "NLS" "$nls") +contents=$(replace "$contents" "PROMPT" "$prompt") +contents=$(replace "$contents" "FUZZ" "$fuzz") +contents=$(replace "$contents" "MEMCHECK" "$memcheck") + +contents=$(replace "$contents" "BC_LIB_O" "$bc_lib") +contents=$(replace "$contents" "BC_HELP_O" "$bc_help") +contents=$(replace "$contents" "DC_HELP_O" "$dc_help") +contents=$(replace "$contents" "BC_LIB2_O" "$BC_LIB2_O") +contents=$(replace "$contents" "KARATSUBA_LEN" "$karatsuba_len") + +contents=$(replace "$contents" "NLSPATH" "$NLSPATH") +contents=$(replace "$contents" "DESTDIR" "$destdir") +contents=$(replace "$contents" "EXECSUFFIX" "$EXECSUFFIX") +contents=$(replace "$contents" "EXECPREFIX" "$EXECPREFIX") +contents=$(replace "$contents" "BINDIR" "$BINDIR") +contents=$(replace "$contents" "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") +contents=$(replace "$contents" "LDFLAGS" "$LDFLAGS") +contents=$(replace "$contents" "CC" "$CC") +contents=$(replace "$contents" "HOSTCC" "$HOSTCC") +contents=$(replace "$contents" "COVERAGE_OUTPUT" "$COVERAGE_OUTPUT") +contents=$(replace "$contents" "COVERAGE_PREREQS" "$COVERAGE_PREREQS") +contents=$(replace "$contents" "INSTALL_PREREQS" "$install_prereqs") +contents=$(replace "$contents" "INSTALL_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" "DEFAULT_TARGET" "$default_target") +contents=$(replace "$contents" "DEFAULT_TARGET_PREREQS" "$default_target_prereqs") +contents=$(replace "$contents" "DEFAULT_TARGET_CMD" "$default_target_cmd") +contents=$(replace "$contents" "SECOND_TARGET" "$second_target") +contents=$(replace "$contents" "SECOND_TARGET_PREREQS" "$second_target_prereqs") +contents=$(replace "$contents" "SECOND_TARGET_CMD" "$second_target_cmd") + +contents=$(replace "$contents" "ALL_PREREQ" "$ALL_PREREQ") +contents=$(replace "$contents" "BC_EXEC_PREREQ" "$bc_exec_prereq") +contents=$(replace "$contents" "BC_EXEC_CMD" "$bc_exec_cmd") +contents=$(replace "$contents" "DC_EXEC_PREREQ" "$dc_exec_prereq") +contents=$(replace "$contents" "DC_EXEC_CMD" "$dc_exec_cmd") + +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" "DC_TEST" "$dc_test") + +contents=$(replace "$contents" "VG_BC_TEST" "$vg_bc_test") +contents=$(replace "$contents" "VG_DC_TEST" "$vg_dc_test") + +contents=$(replace "$contents" "TIMECONST" "$timeconst") + +contents=$(replace "$contents" "KARATSUBA" "$karatsuba") +contents=$(replace "$contents" "KARATSUBA_TEST" "$karatsuba_test") + +contents=$(replace "$contents" "LONG_BIT" "$LONG_BIT") +contents=$(replace "$contents" "LONG_BIT_DEFINE" "$LONG_BIT_DEFINE") + +contents=$(replace "$contents" "GEN" "$GEN") +contents=$(replace "$contents" "GEN_EXEC_TARGET" "$GEN_EXEC_TARGET") +contents=$(replace "$contents" "CLEAN_PREREQS" "$CLEAN_PREREQS") +contents=$(replace "$contents" "GEN_EMU" "$GEN_EMU") + +printf '%s\n%s\n\n' "$contents" "$SRC_TARGETS" > "$scriptdir/Makefile" + +if [ "$bc" -ne 0 ]; then + gen_tests bc BC "$extra_math" "$time_tests" $bc_test_exec + gen_script_tests bc "$extra_math" "$generate_tests" "$time_tests" $bc_test_exec +fi + +if [ "$dc" -ne 0 ]; then + gen_tests dc DC "$extra_math" "$time_tests" $dc_test_exec + gen_script_tests dc "$extra_math" "$generate_tests" "$time_tests" $dc_test_exec +fi + +cd "$scriptdir" + +cp -f manuals/bc/$manpage_args.1.md manuals/bc.1.md +cp -f manuals/bc/$manpage_args.1 manuals/bc.1 +cp -f manuals/dc/$manpage_args.1.md manuals/dc.1.md +cp -f manuals/dc/$manpage_args.1 manuals/dc.1 + +make clean > /dev/null diff --git a/configure.sh b/configure.sh index 310c26882906..af96564e7702 100755 --- a/configure.sh +++ b/configure.sh @@ -1221,6 +1221,8 @@ contents=$(replace "$contents" "DC_TESTS" "$dc_tests") contents=$(replace "$contents" "DC_SCRIPT_TESTS" "$dc_script_tests") contents=$(replace "$contents" "DC_TEST_EXEC" "$dc_test_exec") +contents=$(replace "$contents" "BUILD_TYPE" "$manpage_args") + contents=$(replace "$contents" "LIBRARY" "$library") contents=$(replace "$contents" "HISTORY" "$hist") contents=$(replace "$contents" "EXTRA_MATH" "$extra_math") diff --git a/gen/bc_help.txt b/gen/bc_help.txt index 3f5aac892268..c9b0482d8c42 100644 --- a/gen/bc_help.txt +++ b/gen/bc_help.txt @@ -36,7 +36,8 @@ usage: %s [options] [file...] bc is a command-line, arbitrary-precision calculator with a Turing-complete -language. For details, use `man %s`. +language. For details, use `man %s` or see the online documentation at +https://git.yzena.com/gavin/bc/src/tag/%s/manuals/bc/%s.1.md. This bc is compatible with both the GNU bc and the POSIX bc spec. See the GNU bc manual (https://www.gnu.org/software/bc/manual/bc.html) and bc spec @@ -56,7 +57,7 @@ This bc has three differences to the GNU bc: scripts to work while somewhat preserving expected behavior (versus C) and making parsing easier. 3) This bc has many more extensions than the GNU bc does. For details, see the - man page. + man page or online documentation. This bc also implements the dot (.) extension of the BSD bc. @@ -74,8 +75,8 @@ Options: -g --global-stacks Turn scale, ibase, and obase into stacks. This makes the value of each be - be restored on returning from functions. See the man page for more - details. + be restored on returning from functions. See the man page or online + documentation for more details. -h --help @@ -96,12 +97,16 @@ Options: e(expr) = raises e to the power of expr j(n, x) = Bessel function of integer order n of x - This bc may load more functions with these options. See the manpage for - details. + This bc may load more functions with these options. See the manpage or + online documentation for details. -P --no-prompt - Disable the prompt in interactive mode. + Disable the prompts in interactive mode. + + -R --no-read-prompt + + Disable the read prompt in interactive mode. -q --quiet diff --git a/gen/dc_help.txt b/gen/dc_help.txt index 4b6a61c872f6..c573b96791e7 100644 --- a/gen/dc_help.txt +++ b/gen/dc_help.txt @@ -36,12 +36,13 @@ usage: %s [options] [file...] dc is a reverse-polish notation command-line calculator which supports unlimited -precision arithmetic. For details, use `man %s`. +precision arithmetic. For details, use `man %s` or see the online documentation +at https://git.yzena.com/gavin/bc/src/tag/%s/manuals/bc/%s.1.md. -This dc is (mostly) compatible with the FreeBSD dc and the GNU dc. See the -FreeBSD man page (https://www.unix.com/man-page/FreeBSD/1/dc/) and the GNU dc -manual (https://www.gnu.org/software/bc/manual/dc-1.05/html_mono/dc.html) for -details. +This dc is (mostly) compatible with the OpenBSD dc and the GNU dc. See the +OpenBSD man page (http://man.openbsd.org/OpenBSD-current/man1/dc.1) and the GNU +dc manual (https://www.gnu.org/software/bc/manual/dc-1.05/html_mono/dc.html) +for details. This dc has a few differences from the two above: @@ -90,7 +91,11 @@ Options: -P --no-prompt - Disable the prompt in interactive mode. + Disable the prompts in interactive mode. + + -R --no-read-prompt + + Disable the read prompt in interactive mode. -V --version diff --git a/gen/strgen.c b/gen/strgen.c index 2d133ba51e68..fbc694a37622 100644 --- a/gen/strgen.c +++ b/gen/strgen.c @@ -40,7 +40,9 @@ #include +#ifndef _WIN32 #include +#endif // _WIN32 static const char* const bc_gen_header = "// Copyright (c) 2018-2021 Gavin D. Howard and contributors.\n" @@ -60,6 +62,54 @@ static const char* const bc_gen_name_extern = "extern const char %s[];\n\n"; #define MAX_WIDTH (74) +static void open_file(FILE** f, const char* filename, const char* mode) { + +#ifndef _WIN32 + *f = fopen(filename, mode); +#else // _WIN32 + *f = NULL; + fopen_s(f, filename, mode); +#endif // _WIN32 +} + +static int output_label(FILE* out, const char* label, const char* name) { + +#ifndef _WIN32 + return fprintf(out, bc_gen_label, label, name); +#else // _WIN32 + + size_t i, count = 0, len = strlen(name); + char* buf; + int ret; + + for (i = 0; i < len; ++i) { + count += (name[i] == '\\'); + } + + buf = (char*) malloc(len + 1 + count); + if (buf == NULL) return -1; + + count = 0; + + for (i = 0; i < len; ++i) { + buf[i + count] = name[i]; + if (name[i] == '\\') { + count += 1; + buf[i + count] = name[i]; + } + } + + buf[i + count] = '\0'; + + ret = fprintf(out, bc_gen_label, label, buf); + + free(buf); + + return ret; + +#endif // _WIN32 +} + int main(int argc, char *argv[]) { FILE *in, *out; @@ -82,17 +132,17 @@ int main(int argc, char *argv[]) { remove_tabs = (argc > 6); - in = fopen(argv[1], "r"); + open_file(&in, argv[1], "r"); if (!in) return INVALID_INPUT_FILE; - out = fopen(argv[2], "w"); + open_file(&out, argv[2], "w"); 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 (has_label && fprintf(out, bc_gen_label, label, argv[1]) < 0) goto err; + if (has_label && output_label(out, label, argv[1]) < 0) goto err; if (fprintf(out, bc_gen_name, name) < 0) goto err; c = count = slashes = 0; diff --git a/include/bcl.h b/include/bcl.h index 3c67beb23122..3efb028bab62 100644 --- a/include/bcl.h +++ b/include/bcl.h @@ -36,6 +36,13 @@ #ifndef BC_BCL_H #define BC_BCL_H +#ifdef _WIN32 +#include +#include +#include +#include +#endif // _WIN32 + #include #include #include @@ -74,6 +81,99 @@ typedef uint32_t BclRandInt; #error BC_LONG_BIT must be at least 32 #endif // BC_LONG_BIT >= 64 +#define BC_UNUSED(e) ((void) (e)) + +#ifndef BC_LIKELY +#define BC_LIKELY(e) (e) +#endif // BC_LIKELY + +#ifndef BC_UNLIKELY +#define BC_UNLIKELY(e) (e) +#endif // BC_UNLIKELY + +#define BC_ERR(e) BC_UNLIKELY(e) +#define BC_NO_ERR(s) BC_LIKELY(s) + +#ifndef BC_DEBUG_CODE +#define BC_DEBUG_CODE (0) +#endif // BC_DEBUG_CODE + +#if __STDC_VERSION__ >= 201100L +#include +#define BC_NORETURN _Noreturn +#else // __STDC_VERSION__ +#define BC_NORETURN +#define BC_MUST_RETURN +#endif // __STDC_VERSION__ + +#if defined(__clang__) || defined(__GNUC__) +#if defined(__has_attribute) +#if __has_attribute(fallthrough) +#define BC_FALLTHROUGH __attribute__((fallthrough)); +#else // __has_attribute(fallthrough) +#define BC_FALLTHROUGH +#endif // __has_attribute(fallthrough) +#else // defined(__has_attribute) +#define BC_FALLTHROUGH +#endif // defined(__has_attribute) +#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__ +#endif // SIZE_MAX +#ifndef UINTMAX_C +#define UINTMAX_C __UINTMAX_C +#endif // UINTMAX_C +#ifndef UINT32_C +#define UINT32_C __UINT32_C +#endif // UINT32_C +#ifndef UINT_FAST32_MAX +#define UINT_FAST32_MAX __UINT_FAST32_MAX__ +#endif // UINT_FAST32_MAX +#ifndef UINT16_MAX +#define UINT16_MAX __UINT16_MAX__ +#endif // UINT16_MAX +#ifndef SIG_ATOMIC_MAX +#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__ +#endif // SIG_ATOMIC_MAX + +// Windows has deprecated isatty() and the rest of these. +// Or doesn't have them. +#ifdef _WIN32 + +// This one is special. Windows did not like me defining an +// inline function that was not given a definition in a header +// file. This suppresses that by making inline functions non-inline. +#define inline + +#define restrict __restrict +#define strdup _strdup +#define write(f, b, s) _write((f), (b), (unsigned int) (s)) +#define read(f, b, s) _read((f), (b), (unsigned int) (s)) +#define close _close +#define open(f, n, m) _sopen_s(f, n, m, _SH_DENYNO, _S_IREAD | _S_IWRITE) +#define sigjmp_buf jmp_buf +#define sigsetjmp(j, s) setjmp(j) +#define siglongjmp longjmp +#define isatty _isatty +#define STDIN_FILENO (0) +#define STDOUT_FILENO (1) +#define STDERR_FILENO (2) +#define ssize_t SSIZE_T +#define S_ISDIR(m) ((m) & _S_IFDIR) +#define O_RDONLY _O_RDONLY +#define stat _stat +#define fstat _fstat +#define BC_FILE_SEP '\\' + +#else // _WIN32 +#define BC_FILE_SEP '/' +#endif // _WIN32 + +#if BC_ENABLE_LIBRARY typedef enum BclError { @@ -181,4 +281,6 @@ BclNumber bcl_rand_seed2num(void); BclRandInt bcl_rand_int(void); BclRandInt bcl_rand_bounded(BclRandInt bound); +#endif // BC_ENABLE_LIBRARY + #endif // BC_BCL_H diff --git a/include/file.h b/include/file.h index 1c3273b7a756..fbd4b9b9f9b3 100644 --- a/include/file.h +++ b/include/file.h @@ -51,15 +51,39 @@ typedef struct BcFile { } BcFile; +#if BC_ENABLE_HISTORY +typedef enum BcFlushType { + + BC_FLUSH_NO_EXTRAS_NO_CLEAR, + BC_FLUSH_SAVE_EXTRAS_NO_CLEAR, + BC_FLUSH_NO_EXTRAS_CLEAR, + BC_FLUSH_SAVE_EXTRAS_CLEAR, + +} BcFlushType; +#else // BC_ENABLE_HISTORY +#define bc_file_putchar(f, t, c) bc_file_putchar(f, c) +#define bc_file_flushErr(f, t) bc_file_flushErr(f) +#define bc_file_flush(f, t) bc_file_flush(f) +#define bc_file_write(f, t, b, n) bc_file_write(f, b, n) +#define bc_file_puts(f, t, s) bc_file_puts(f, s) +#endif // BC_ENABLE_HISTORY + void bc_file_init(BcFile *f, int fd, char *buf, size_t cap); void bc_file_free(BcFile *f); -void bc_file_putchar(BcFile *restrict f, uchar c); -BcStatus bc_file_flushErr(BcFile *restrict f); -void bc_file_flush(BcFile *restrict f); -void bc_file_write(BcFile *restrict f, const char *buf, size_t n); +void bc_file_putchar(BcFile *restrict f, BcFlushType type, uchar c); +BcStatus bc_file_flushErr(BcFile *restrict f, BcFlushType type); +void bc_file_flush(BcFile *restrict f, BcFlushType type); +void bc_file_write(BcFile *restrict f, BcFlushType type, + const char *buf, size_t n); void bc_file_printf(BcFile *restrict f, const char *fmt, ...); void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args); -void bc_file_puts(BcFile *restrict f, const char *str); +void bc_file_puts(BcFile *restrict f, BcFlushType type, const char *str); + +#if BC_ENABLE_HISTORY +extern const BcFlushType bc_flush_none; +extern const BcFlushType bc_flush_err; +extern const BcFlushType bc_flush_save; +#endif // BC_ENABLE_HISTORY #endif // BC_FILE_H diff --git a/include/history.h b/include/history.h index d3622ae15a30..469785a118a9 100644 --- a/include/history.h +++ b/include/history.h @@ -186,6 +186,9 @@ typedef struct BcHistory { /// The history. BcVec history; + /// Any material printed without a trailing newline. + BcVec extras; + #if BC_ENABLE_PROMPT /// Prompt to display. const char *prompt; diff --git a/include/num.h b/include/num.h index 2104f8b8acad..8beea00189db 100644 --- a/include/num.h +++ b/include/num.h @@ -172,9 +172,10 @@ struct BcRNG; #endif // BC_DEBUG_CODE typedef void (*BcNumBinaryOp)(BcNum*, BcNum*, BcNum*, size_t); +typedef void (*BcNumBinOp)(BcNum*, BcNum*, BcNum* restrict, size_t); typedef size_t (*BcNumBinaryOpReq)(const BcNum*, const BcNum*, size_t); typedef void (*BcNumDigitOp)(size_t, size_t, bool); -typedef void (*BcNumShiftAddOp)(BcDig*, const BcDig*, size_t); +typedef void (*BcNumShiftAddOp)(BcDig* restrict, const BcDig* restrict, size_t); void bc_num_init(BcNum *restrict n, size_t req); void bc_num_setup(BcNum *restrict n, BcDig *restrict num, size_t cap); diff --git a/include/status.h b/include/status.h index cf41a3ce4670..be2356497f94 100644 --- a/include/status.h +++ b/include/status.h @@ -150,63 +150,4 @@ typedef enum BcErr { #define BC_ERR_IDX_WARN (BC_ERR_IDX_NELEMS) #endif // BC_ENABLED -#define BC_UNUSED(e) ((void) (e)) - -#ifndef BC_LIKELY -#define BC_LIKELY(e) (e) -#endif // BC_LIKELY - -#ifndef BC_UNLIKELY -#define BC_UNLIKELY(e) (e) -#endif // BC_UNLIKELY - -#define BC_ERR(e) BC_UNLIKELY(e) -#define BC_NO_ERR(s) BC_LIKELY(s) - -#ifndef BC_DEBUG_CODE -#define BC_DEBUG_CODE (0) -#endif // BC_DEBUG_CODE - -#if __STDC_VERSION__ >= 201100L -#include -#define BC_NORETURN _Noreturn -#else // __STDC_VERSION__ -#define BC_NORETURN -#define BC_MUST_RETURN -#endif // __STDC_VERSION__ - -#if defined(__clang__) || defined(__GNUC__) -#if defined(__has_attribute) -#if __has_attribute(fallthrough) -#define BC_FALLTHROUGH __attribute__((fallthrough)); -#else // __has_attribute(fallthrough) -#define BC_FALLTHROUGH -#endif // __has_attribute(fallthrough) -#else // defined(__has_attribute) -#define BC_FALLTHROUGH -#endif // defined(__has_attribute) -#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__ -#endif // SIZE_MAX -#ifndef UINTMAX_C -#define UINTMAX_C __UINTMAX_C -#endif // UINTMAX_C -#ifndef UINT32_C -#define UINT32_C __UINT32_C -#endif // UINT32_C -#ifndef UINT_FAST32_MAX -#define UINT_FAST32_MAX __UINT_FAST32_MAX__ -#endif // UINT_FAST32_MAX -#ifndef UINT16_MAX -#define UINT16_MAX __UINT16_MAX__ -#endif // UINT16_MAX -#ifndef SIG_ATOMIC_MAX -#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__ -#endif // SIG_ATOMIC_MAX - #endif // BC_STATUS_H diff --git a/include/version.h b/include/version.h new file mode 100644 index 000000000000..7f33df62312e --- /dev/null +++ b/include/version.h @@ -0,0 +1,41 @@ +/* + * ***************************************************************************** + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2018-2021 Gavin D. Howard and contributors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * ***************************************************************************** + * + * Definitions for processing command-line arguments. + * + */ + +#ifndef BC_VERSION_H +#define BC_VERSION_H + +#define VERSION 4.0.0 + +#endif // BC_VERSION_H diff --git a/include/vm.h b/include/vm.h index 80a060edd42f..8d726ffec1cc 100644 --- a/include/vm.h +++ b/include/vm.h @@ -52,6 +52,7 @@ #endif // BC_ENABLE_NLS +#include #include #include #include @@ -77,22 +78,27 @@ #ifndef MAINEXEC #define MAINEXEC bc -#endif +#endif // MAINEXEC +#ifndef _WIN32 #ifndef EXECPREFIX #define EXECPREFIX -#endif +#endif // EXECPREFIX +#else // _WIN32 +#undef EXECPREFIX +#endif // _WIN32 #define GEN_STR(V) #V #define GEN_STR2(V) GEN_STR(V) #define BC_VERSION GEN_STR2(VERSION) -#define BC_EXECPREFIX GEN_STR2(EXECPREFIX) #define BC_MAINEXEC GEN_STR2(MAINEXEC) +#define BC_BUILD_TYPE GEN_STR2(BUILD_TYPE) -// Windows has deprecated isatty(). -#ifdef _WIN32 -#define isatty _isatty +#ifndef _WIN32 +#define BC_EXECPREFIX GEN_STR2(EXECPREFIX) +#else // _WIN32 +#define BC_EXECPREFIX "" #endif // _WIN32 #if !BC_ENABLE_LIBRARY @@ -110,8 +116,9 @@ #define BC_FLAG_I (UINTMAX_C(1)<<5) #define BC_FLAG_P (UINTMAX_C(1)<<6) -#define BC_FLAG_TTYIN (UINTMAX_C(1)<<7) -#define BC_FLAG_TTY (UINTMAX_C(1)<<8) +#define BC_FLAG_R (UINTMAX_C(1)<<7) +#define BC_FLAG_TTYIN (UINTMAX_C(1)<<8) +#define BC_FLAG_TTY (UINTMAX_C(1)<<9) #define BC_TTYIN (vm.flags & BC_FLAG_TTYIN) #define BC_TTY (vm.flags & BC_FLAG_TTY) @@ -130,6 +137,7 @@ #define BC_I (vm.flags & BC_FLAG_I) #define BC_P (vm.flags & BC_FLAG_P) +#define BC_R (vm.flags & BC_FLAG_R) #if BC_ENABLED @@ -421,13 +429,19 @@ void bc_vm_init(void); void bc_vm_shutdown(void); void bc_vm_freeTemps(void); +#if !BC_ENABLE_HISTORY +#define bc_vm_putchar(c, t) bc_vm_putchar(c) +#endif // !BC_ENABLE_HISTORY + void bc_vm_printf(const char *fmt, ...); -void bc_vm_putchar(int c); +void bc_vm_putchar(int c, BcFlushType type); size_t bc_vm_arraySize(size_t n, size_t size); size_t bc_vm_growSize(size_t a, size_t b); void* bc_vm_malloc(size_t n); void* bc_vm_realloc(void *ptr, size_t n); char* bc_vm_strdup(const char *str); +char* bc_vm_getenv(const char* var); +void bc_vm_getenvFree(char* var); #if BC_DEBUG_CODE void bc_vm_jmp(const char *f); diff --git a/karatsuba.py b/karatsuba.py index cfab4c4f4fbf..0a63cd58b08b 100755 --- a/karatsuba.py +++ b/karatsuba.py @@ -121,20 +121,20 @@ def run(cmd, env=None): p = run([ "make", "clean" ]) -print("Testing \"make -j12\"") +print("Testing \"make -j16\"") if p.returncode != 0: print("make returned an error ({}); exiting...".format(p.returncode)) sys.exit(p.returncode) -p = run([ "make", "-j12" ]) +p = run([ "make", "-j16" ]) if p.returncode == 0: - makecmd = [ "make", "-j12" ] - print("Using \"make -j12\"") + makecmd = [ "make", "-j16" ] + print("Using \"make -j16\"") else: makecmd = [ "make" ] - print("Not using \"make -j12\"") + print("Not using \"make -j16\"") if test_num != 0: mx2 = test_num diff --git a/manpage.sh b/manpage.sh index f774bfdb3b20..b855b3092969 100755 --- a/manpage.sh +++ b/manpage.sh @@ -43,7 +43,7 @@ print_manpage() { 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" + pandoc -f commonmark -t man "$_print_manpage_md" >> "$_print_manpage_out" } diff --git a/manuals/bc.1.md.in b/manuals/bc.1.md.in index 661fcdd45ae4..d182dd7ab411 100644 --- a/manuals/bc.1.md.in +++ b/manuals/bc.1.md.in @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -181,7 +181,7 @@ The following are the options that bc(1) accepts. {{ A E H N EH EN HN EHN }} : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in **BC_ENV_ARGS** (see the **ENVIRONMENT VARIABLES** section). @@ -192,6 +192,25 @@ The following are the options that bc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +{{ A E H N EH EN HN EHN }} +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in bc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of bc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **read()** built-in function is called. +{{ end }} +{{ P EP HP NP EHP ENP HNP EHNP }} +: Because bc(1) was built without support for prompts, this option is a no-op. +{{ end }} + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/A.1 b/manuals/bc/A.1 index b38d8d35e71b..2cb0a11943cc 100644 --- a/manuals/bc/A.1 +++ b/manuals/bc/A.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -58,210 +58,233 @@ implementations. .SH OPTIONS .PP The following are the options that bc(1) accepts. -.TP +.PP \f[B]-g\f[R], \f[B]--global-stacks\f[R] -Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and -\f[B]seed\f[R] into stacks. -.RS .PP -This has the effect that a copy of the current value of all four are -pushed onto a stack for every function call, as well as popped when -every function returns. -This means that functions can assign to any and all of those globals -without worrying that the change will affect other functions. -Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply -printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this: +: Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], +and \f[B]seed\f[R] into stacks. .IP .nf \f[C] -define void output(x, b) { - obase=b - x -} -\f[R] -.fi -.PP +This has the effect that a copy of the current value of all four are pushed +onto a stack for every function call, as well as popped when every function +returns. This means that functions can assign to any and all of those +globals without worrying that the change will affect other functions. +Thus, a hypothetical function named **output(x,b)** that simply printed +**x** in base **b** could be written like this: + + define void output(x, b) { + obase=b + x + } + instead of like this: -.IP -.nf -\f[C] -define void output(x, b) { - auto c - c=obase - obase=b - x - obase=c -} -\f[R] -.fi -.PP + + define void output(x, b) { + auto c + c=obase + obase=b + x + obase=c + } + This makes writing functions much easier. -.PP -(\f[B]Note\f[R]: the function \f[B]output(x,b)\f[R] exists in the -extended math library. -See the \f[B]LIBRARY\f[R] section.) -.PP -However, since using this flag means that functions cannot set -\f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] -globally, functions that are made to do so cannot work anymore. -There are two possible use cases for that, and each has a solution. -.PP + +(**Note**: the function **output(x,b)** exists in the extended math library. + See the **LIBRARY** section.) + +However, since using this flag means that functions cannot set **ibase**, +**obase**, **scale**, or **seed** globally, functions that are made to do so +cannot work anymore. There are two possible use cases for that, and each has +a solution. + First, if a function is called on startup to turn bc(1) into a number converter, it is possible to replace that capability with various shell -aliases. -Examples: -.IP -.nf -\f[C] -alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] -alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] +aliases. Examples: + + alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] + alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] + +Second, if the purpose of a function is to set **ibase**, **obase**, +**scale**, or **seed** globally for any other purpose, it could be split +into one to four functions (based on how many globals it sets) and each of +those functions could return the desired value for a global. + +For functions that set **seed**, the value assigned to **seed** is not +propagated to parent functions. This means that the sequence of +pseudo-random numbers that they see will not be the same sequence of +pseudo-random numbers that any parent sees. This is only the case once +**seed** has been set. + +If a function desires to not affect the sequence of pseudo-random numbers +of its parents, but wants to use the same **seed**, it can use the following +line: + + seed = seed + +If the behavior of this option is desired for every run of bc(1), then users +could make sure to define **BC_ENV_ARGS** and include this option (see the +**ENVIRONMENT VARIABLES** section for more details). + +If **-s**, **-w**, or any equivalents are used, this option is ignored. + +This is a **non-portable extension**. \f[R] .fi .PP -Second, if the purpose of a function is to set \f[B]ibase\f[R], -\f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] globally for any -other purpose, it could be split into one to four functions (based on -how many globals it sets) and each of those functions could return the -desired value for a global. -.PP -For functions that set \f[B]seed\f[R], the value assigned to -\f[B]seed\f[R] is not propagated to parent functions. -This means that the sequence of pseudo-random numbers that they see will -not be the same sequence of pseudo-random numbers that any parent sees. -This is only the case once \f[B]seed\f[R] has been set. -.PP -If a function desires to not affect the sequence of pseudo-random -numbers of its parents, but wants to use the same \f[B]seed\f[R], it can -use the following line: -.IP -.nf -\f[C] -seed = seed -\f[R] -.fi -.PP -If the behavior of this option is desired for every run of bc(1), then -users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this -option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more -details). -.PP -If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option -is ignored. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library and the extended math library before -running any code, including any expressions or files specified on the -command line. -.RS .PP -To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library and the extended math +library before running any code, including any expressions or files +specified on the command line. +.IP +.nf +\f[C] +To learn what is in the libraries, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in \f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in bc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of bc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **read()** built-in function is called. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -318,7 +341,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -330,7 +353,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -502,7 +525,7 @@ This is a \f[B]non-portable extension\f[R]. .IP "15." 4 \f[B]irand(E)\f[R]: A pseudo-random integer between \f[B]0\f[R] (inclusive) and the value of \f[B]E\f[R] (exclusive). -If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[cq]s +If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[aq]s \f[I]scale\f[R] is not \f[B]0\f[R]), an error is raised, and bc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] remains unchanged. @@ -580,301 +603,377 @@ extension\f[R]. The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]$\f[R] -Type: Postfix -.RS .PP +: Type: Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **truncation** +\f[R] +.fi .PP -Description: \f[B]truncation\f[R] -.RE -.TP \f[B]\[at]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **set precision** +\f[R] +.fi .PP -Description: \f[B]set precision\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP \f[B]<<\f[R] \f[B]>>\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **shift left**, **shift right** +\f[R] +.fi .PP -Description: \f[B]shift left\f[R], \f[B]shift right\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP +.PP \f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]$\f[R] -The \f[B]truncation\f[R] operator returns a copy of the given expression -with all of its \f[I]scale\f[R] removed. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]truncation\f[R] operator returns a copy of the given +expression with all of its \f[I]scale\f[R] removed. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The \f[B]set precision\f[R] operator takes two expressions and returns a -copy of the first with its \f[I]scale\f[R] equal to the value of the +.PP +: The \f[B]set precision\f[R] operator takes two expressions and returns +a copy of the first with its \f[I]scale\f[R] equal to the value of the second expression. That could either mean that the number is returned without change (if the \f[I]scale\f[R] of the first expression matches the value of the second expression), extended (if it is less), or truncated (if it is more). -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]<<\f[R] -The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] and -\f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its +.PP +: The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] +and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the right. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]>>\f[R] -The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] +.PP +: The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the left. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. + +The **assignment** operators that correspond to operators that are +extensions are themselves **non-portable extensions**. +\f[R] +.fi .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP -The \f[B]assignment\f[R] operators that correspond to operators that are -extensions are themselves \f[B]non-portable extensions\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -900,7 +999,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -958,62 +1058,22 @@ Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -1109,9 +1169,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -1146,55 +1206,74 @@ are given. The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Extended Library .PP The extended library is \f[I]not\f[R] loaded when the @@ -1203,99 +1282,126 @@ options are given since they are not part of the library defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html). .PP The extended library is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p(x, y)\f[R] -Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if \f[B]y\f[R] -is not an integer, and returns the result to the current +.PP +: Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if +\f[B]y\f[R] is not an integer, and returns the result to the current \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +It is an error if **y** is negative and **x** is **0**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -It is an error if \f[B]y\f[R] is negative and \f[B]x\f[R] is -\f[B]0\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round half away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). -.TP +.PP \f[B]ceil(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero). -.TP +.PP \f[B]f(x)\f[R] -Returns the factorial of the truncated absolute value of \f[B]x\f[R]. -.TP +.PP +: Returns the factorial of the truncated absolute value of \f[B]x\f[R]. +.PP \f[B]perm(n, k)\f[R] -Returns the permutation of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the permutation of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]comb(n, k)\f[R] -Returns the combination of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the combination of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]l2(x)\f[R] -Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l10(x)\f[R] -Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]log(x, b)\f[R] -Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]cbrt(x)\f[R] -Returns the cube root of \f[B]x\f[R]. -.TP +.PP +: Returns the cube root of \f[B]x\f[R]. +.PP \f[B]root(x, n)\f[R] -Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and returns -the \f[B]r\f[R]th root of \f[B]x\f[R] to the current \f[B]scale\f[R]. -.RS .PP -If \f[B]r\f[R] is \f[B]0\f[R] or negative, this raises an error and -causes bc(1) to reset (see the \f[B]RESET\f[R] section). -It also raises an error and causes bc(1) to reset if \f[B]r\f[R] is even -and \f[B]x\f[R] is negative. -.RE -.TP +: Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and +returns the \f[B]r\f[R]th root of \f[B]x\f[R] to the current +\f[B]scale\f[R]. +.IP +.nf +\f[C] +If **r** is **0** or negative, this raises an error and causes bc(1) to +reset (see the **RESET** section). It also raises an error and causes bc(1) +to reset if **r** is even and **x** is negative. +\f[R] +.fi +.PP \f[B]pi(p)\f[R] -Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]t(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1308,60 +1414,75 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]sin(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]s(x)\f[R]. +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **s(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]cos(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]c(x)\f[R]. +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **c(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]tan(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -If \f[B]x\f[R] is equal to \f[B]1\f[R] or \f[B]-1\f[R], this raises an -error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +If **x** is equal to **1** or **-1**, this raises an error and causes bc(1) +to reset (see the **RESET** section). + +This is an alias of **t(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is an alias of \f[B]t(x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is an alias of \f[B]a(x)\f[R]. +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is an alias of **a(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1374,302 +1495,367 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is an alias of **a2(y, x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is an alias of \f[B]a2(y, x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r2d(x)\f[R] -Converts \f[B]x\f[R] from radians to degrees and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from radians to degrees and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]d2r(x)\f[R] -Converts \f[B]x\f[R] from degrees to radians and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from degrees to radians and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]frand(p)\f[R] -Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and +.PP +: Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R] (exclusive) with the number of decimal digits after the decimal point equal to the truncated absolute value of \f[B]p\f[R]. If \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]. If \f[B]p\f[R] is \f[B]0\f[R], then \f[B]0\f[R] is returned, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.TP +.PP \f[B]ifrand(i, p)\f[R] -Generates a pseudo-random number that is between \f[B]0\f[R] (inclusive) -and the truncated absolute value of \f[B]i\f[R] (exclusive) with the -number of decimal digits after the decimal point equal to the truncated -absolute value of \f[B]p\f[R]. +.PP +: Generates a pseudo-random number that is between \f[B]0\f[R] +(inclusive) and the truncated absolute value of \f[B]i\f[R] (exclusive) +with the number of decimal digits after the decimal point equal to the +truncated absolute value of \f[B]p\f[R]. If the absolute value of \f[B]i\f[R] is greater than or equal to \f[B]2\f[R], and \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]; otherwise, \f[B]0\f[R] is returned and \f[B]seed\f[R] is not changed. -.TP +.PP \f[B]srand(x)\f[R] -Returns \f[B]x\f[R] with its sign flipped with probability +.PP +: Returns \f[B]x\f[R] with its sign flipped with probability \f[B]0.5\f[R]. In other words, it randomizes the sign of \f[B]x\f[R]. -.TP +.PP \f[B]brand()\f[R] -Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). -.TP +.PP +: Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). +.PP \f[B]ubytes(x)\f[R] -Returns the numbers of unsigned integer bytes required to hold the +.PP +: Returns the numbers of unsigned integer bytes required to hold the truncated absolute value of \f[B]x\f[R]. -.TP +.PP \f[B]sbytes(x)\f[R] -Returns the numbers of signed, two\[cq]s-complement integer bytes +.PP +: Returns the numbers of signed, two\[aq]s-complement integer bytes required to hold the truncated value of \f[B]x\f[R]. -.TP +.PP \f[B]hex(x)\f[R] -Outputs the hexadecimal (base \f[B]16\f[R]) representation of +.PP +: Outputs the hexadecimal (base \f[B]16\f[R]) representation of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary(x)\f[R] -Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]output(x, b)\f[R] -Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]uint(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in as few power of two bytes as possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or is negative, an error message is printed +instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or is negative, an error message is -printed instead, but bc(1) is not reset (see the \f[B]RESET\f[R] -section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in as few power of two bytes as -possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in as few power of two bytes +as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, an error message is printed instead, but bc(1) +is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, an error message is printed instead, -but bc(1) is not reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uintn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **n** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]n\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]intn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **n** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]n\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **1** byte, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]1\f[R] byte, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **1** byte, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]1\f[R] byte, an -error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **2** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]2\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **2** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]2\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **4** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]4\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **4** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]4\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **8** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]8\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **8** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]8\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]hex_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in hexadecimal using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in binary using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in the current \f[B]obase\f[R] (see the \f[B]SYNTAX\f[R] section) using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_byte(x, i)\f[R] -Outputs byte \f[B]i\f[R] of the truncated absolute value of \f[B]x\f[R], -where \f[B]0\f[R] is the least significant byte and \f[B]number_of_bytes -- 1\f[R] is the most significant byte. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE +: Outputs byte \f[B]i\f[R] of the truncated absolute value of +\f[B]x\f[R], where \f[B]0\f[R] is the least significant byte and +\f[B]number_of_bytes - 1\f[R] is the most significant byte. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1773,64 +1959,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]rand()\f[R] +.PP +: The maximum integer (inclusive) returned by the \f[B]rand()\f[R] operand. Set at \f[B]2\[ha]BC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1842,42 +2041,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1885,68 +2086,76 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**\[rs]<\[rs]<**), and right shift (**\[rs]>\[rs]>**) +operators and their corresponding assignment operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]<<\f[R]), and right shift (\f[B]>>\f[R]) operators and their -corresponding assignment operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1976,7 +2185,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1998,7 +2207,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/A.1.md b/manuals/bc/A.1.md index 04f37c6bb724..847d7c312310 100644 --- a/manuals/bc/A.1.md +++ b/manuals/bc/A.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -143,13 +143,27 @@ The following are the options that bc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in **BC_ENV_ARGS** (see the **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in bc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of bc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **read()** built-in function is called. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/E.1 b/manuals/bc/E.1 index 9023b07c6b87..6600e9da5eaa 100644 --- a/manuals/bc/E.1 +++ b/manuals/bc/E.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -113,117 +113,159 @@ If **-s**, **-w**, or any equivalents are used, this option is ignored. This is a **non-portable extension**. \f[R] .fi -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library before running any code, including -any expressions or files specified on the command line. -.RS .PP -To learn what is in the library, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library before running any +code, including any expressions or files specified on the command line. +.IP +.nf +\f[C] +To learn what is in the library, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in \f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in bc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of bc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **read()** built-in function is called. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -280,7 +322,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -292,7 +334,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -443,223 +485,281 @@ This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP -\f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]!\f[R] +.PP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] +.PP +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. +\f[R] +.fi +.PP +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] +.PP +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -685,7 +785,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -729,62 +830,22 @@ command. An expression by itself is evaluated and printed, followed by a newline. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -880,9 +941,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -913,55 +974,74 @@ All of the functions below are available when the \f[B]-l\f[R] or The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1037,59 +1117,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1101,42 +1193,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1144,65 +1238,74 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator and the corresponding assignment operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator and the corresponding assignment -operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1232,7 +1335,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1254,7 +1357,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/E.1.md b/manuals/bc/E.1.md index 589050cb89b5..478f298eeeb2 100644 --- a/manuals/bc/E.1.md +++ b/manuals/bc/E.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -127,13 +127,27 @@ The following are the options that bc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in **BC_ENV_ARGS** (see the **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in bc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of bc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **read()** built-in function is called. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/EH.1 b/manuals/bc/EH.1 index 53f95b2f7c09..696e25c5a657 100644 --- a/manuals/bc/EH.1 +++ b/manuals/bc/EH.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -110,117 +110,159 @@ If **-s**, **-w**, or any equivalents are used, this option is ignored. This is a **non-portable extension**. \f[R] .fi -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library before running any code, including -any expressions or files specified on the command line. -.RS .PP -To learn what is in the library, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library before running any +code, including any expressions or files specified on the command line. +.IP +.nf +\f[C] +To learn what is in the library, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in \f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in bc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of bc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **read()** built-in function is called. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -277,7 +319,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -289,7 +331,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -440,223 +482,281 @@ This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP -\f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]!\f[R] +.PP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] +.PP +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. +\f[R] +.fi +.PP +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] +.PP +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -682,7 +782,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -726,62 +827,22 @@ command. An expression by itself is evaluated and printed, followed by a newline. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -877,9 +938,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -910,55 +971,74 @@ All of the functions below are available when the \f[B]-l\f[R] or The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1034,59 +1114,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1098,42 +1190,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1141,65 +1235,74 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator and the corresponding assignment operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator and the corresponding assignment -operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1229,7 +1332,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP The prompt is enabled in TTY mode. .PP @@ -1246,7 +1349,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/EH.1.md b/manuals/bc/EH.1.md index bfd08efb3830..51a9f93549fa 100644 --- a/manuals/bc/EH.1.md +++ b/manuals/bc/EH.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -124,13 +124,27 @@ The following are the options that bc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in **BC_ENV_ARGS** (see the **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in bc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of bc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **read()** built-in function is called. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/EHN.1 b/manuals/bc/EHN.1 index 0870115dca2a..bbfeb207b35c 100644 --- a/manuals/bc/EHN.1 +++ b/manuals/bc/EHN.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -110,117 +110,159 @@ If **-s**, **-w**, or any equivalents are used, this option is ignored. This is a **non-portable extension**. \f[R] .fi -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library before running any code, including -any expressions or files specified on the command line. -.RS .PP -To learn what is in the library, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library before running any +code, including any expressions or files specified on the command line. +.IP +.nf +\f[C] +To learn what is in the library, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in \f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in bc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of bc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **read()** built-in function is called. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -277,7 +319,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -289,7 +331,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -440,223 +482,281 @@ This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP -\f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]!\f[R] +.PP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] +.PP +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. +\f[R] +.fi +.PP +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] +.PP +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -682,7 +782,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -726,62 +827,22 @@ command. An expression by itself is evaluated and printed, followed by a newline. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -877,9 +938,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -910,55 +971,74 @@ All of the functions below are available when the \f[B]-l\f[R] or The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1034,59 +1114,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1098,42 +1190,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1141,65 +1235,74 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator and the corresponding assignment operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator and the corresponding assignment -operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1229,7 +1332,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP The prompt is enabled in TTY mode. .PP @@ -1246,7 +1349,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/EHN.1.md b/manuals/bc/EHN.1.md index 15b851ee19b0..aab79e932b04 100644 --- a/manuals/bc/EHN.1.md +++ b/manuals/bc/EHN.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -124,13 +124,27 @@ The following are the options that bc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in **BC_ENV_ARGS** (see the **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in bc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of bc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **read()** built-in function is called. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/EHNP.1 b/manuals/bc/EHNP.1 index f6728d5b2221..ade3294dd49a 100644 --- a/manuals/bc/EHNP.1 +++ b/manuals/bc/EHNP.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -110,112 +110,145 @@ If **-s**, **-w**, or any equivalents are used, this option is ignored. This is a **non-portable extension**. \f[R] .fi -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library before running any code, including -any expressions or files specified on the command line. -.RS .PP -To learn what is in the library, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library before running any +code, including any expressions or files specified on the command line. +.IP +.nf +\f[C] +To learn what is in the library, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Because bc(1) was built without support for prompts, this option is a +no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -272,7 +305,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -284,7 +317,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -435,223 +468,281 @@ This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP -\f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]!\f[R] +.PP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] +.PP +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. +\f[R] +.fi +.PP +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] +.PP +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -677,7 +768,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -721,62 +813,22 @@ command. An expression by itself is evaluated and printed, followed by a newline. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -872,9 +924,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -905,55 +957,74 @@ All of the functions below are available when the \f[B]-l\f[R] or The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1029,59 +1100,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1093,42 +1176,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1136,65 +1221,74 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator and the corresponding assignment operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator and the corresponding assignment -operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1224,7 +1318,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is different from interactive mode because interactive mode is required in the bc(1) @@ -1239,7 +1333,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/EHNP.1.md b/manuals/bc/EHNP.1.md index a0e1b71f8d38..d7afa1ccc1af 100644 --- a/manuals/bc/EHNP.1.md +++ b/manuals/bc/EHNP.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -127,6 +127,12 @@ The following are the options that bc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Because bc(1) was built without support for prompts, this option is a no-op. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/EHP.1 b/manuals/bc/EHP.1 index dc3476f68b92..b5cfe948d5e8 100644 --- a/manuals/bc/EHP.1 +++ b/manuals/bc/EHP.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -110,112 +110,145 @@ If **-s**, **-w**, or any equivalents are used, this option is ignored. This is a **non-portable extension**. \f[R] .fi -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library before running any code, including -any expressions or files specified on the command line. -.RS .PP -To learn what is in the library, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library before running any +code, including any expressions or files specified on the command line. +.IP +.nf +\f[C] +To learn what is in the library, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Because bc(1) was built without support for prompts, this option is a +no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -272,7 +305,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -284,7 +317,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -435,223 +468,281 @@ This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP -\f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]!\f[R] +.PP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] +.PP +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. +\f[R] +.fi +.PP +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] +.PP +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -677,7 +768,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -721,62 +813,22 @@ command. An expression by itself is evaluated and printed, followed by a newline. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -872,9 +924,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -905,55 +957,74 @@ All of the functions below are available when the \f[B]-l\f[R] or The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1029,59 +1100,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1093,42 +1176,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1136,65 +1221,74 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator and the corresponding assignment operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator and the corresponding assignment -operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1224,7 +1318,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is different from interactive mode because interactive mode is required in the bc(1) @@ -1239,7 +1333,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/EHP.1.md b/manuals/bc/EHP.1.md index 976ae8eb11b7..e6338f70e396 100644 --- a/manuals/bc/EHP.1.md +++ b/manuals/bc/EHP.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -127,6 +127,12 @@ The following are the options that bc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Because bc(1) was built without support for prompts, this option is a no-op. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/EN.1 b/manuals/bc/EN.1 index e6e7b3c5f145..3ea500b95b3f 100644 --- a/manuals/bc/EN.1 +++ b/manuals/bc/EN.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -113,117 +113,159 @@ If **-s**, **-w**, or any equivalents are used, this option is ignored. This is a **non-portable extension**. \f[R] .fi -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library before running any code, including -any expressions or files specified on the command line. -.RS .PP -To learn what is in the library, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library before running any +code, including any expressions or files specified on the command line. +.IP +.nf +\f[C] +To learn what is in the library, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in \f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in bc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of bc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **read()** built-in function is called. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -280,7 +322,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -292,7 +334,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -443,223 +485,281 @@ This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP -\f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]!\f[R] +.PP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] +.PP +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. +\f[R] +.fi +.PP +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] +.PP +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -685,7 +785,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -729,62 +830,22 @@ command. An expression by itself is evaluated and printed, followed by a newline. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -880,9 +941,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -913,55 +974,74 @@ All of the functions below are available when the \f[B]-l\f[R] or The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1037,59 +1117,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1101,42 +1193,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1144,65 +1238,74 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator and the corresponding assignment operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator and the corresponding assignment -operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1232,7 +1335,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1254,7 +1357,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/EN.1.md b/manuals/bc/EN.1.md index 6dc19727c982..4e0a0f0fb8b4 100644 --- a/manuals/bc/EN.1.md +++ b/manuals/bc/EN.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -127,13 +127,27 @@ The following are the options that bc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in **BC_ENV_ARGS** (see the **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in bc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of bc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **read()** built-in function is called. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/ENP.1 b/manuals/bc/ENP.1 index f96fe194cda1..e4452bd876f5 100644 --- a/manuals/bc/ENP.1 +++ b/manuals/bc/ENP.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -113,112 +113,145 @@ If **-s**, **-w**, or any equivalents are used, this option is ignored. This is a **non-portable extension**. \f[R] .fi -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library before running any code, including -any expressions or files specified on the command line. -.RS .PP -To learn what is in the library, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library before running any +code, including any expressions or files specified on the command line. +.IP +.nf +\f[C] +To learn what is in the library, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Because bc(1) was built without support for prompts, this option is a +no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -275,7 +308,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -287,7 +320,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -438,223 +471,281 @@ This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP -\f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]!\f[R] +.PP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] +.PP +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. +\f[R] +.fi +.PP +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] +.PP +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -680,7 +771,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -724,62 +816,22 @@ command. An expression by itself is evaluated and printed, followed by a newline. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -875,9 +927,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -908,55 +960,74 @@ All of the functions below are available when the \f[B]-l\f[R] or The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1032,59 +1103,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1096,42 +1179,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1139,65 +1224,74 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator and the corresponding assignment operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator and the corresponding assignment -operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1227,7 +1321,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1247,7 +1341,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/ENP.1.md b/manuals/bc/ENP.1.md index 20b60a7a9081..6c6dd2780e81 100644 --- a/manuals/bc/ENP.1.md +++ b/manuals/bc/ENP.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -130,6 +130,12 @@ The following are the options that bc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Because bc(1) was built without support for prompts, this option is a no-op. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/EP.1 b/manuals/bc/EP.1 index 62ee57bfccc7..453b768082ed 100644 --- a/manuals/bc/EP.1 +++ b/manuals/bc/EP.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -113,112 +113,145 @@ If **-s**, **-w**, or any equivalents are used, this option is ignored. This is a **non-portable extension**. \f[R] .fi -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library before running any code, including -any expressions or files specified on the command line. -.RS .PP -To learn what is in the library, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library before running any +code, including any expressions or files specified on the command line. +.IP +.nf +\f[C] +To learn what is in the library, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Because bc(1) was built without support for prompts, this option is a +no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -275,7 +308,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -287,7 +320,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -438,223 +471,281 @@ This means that \f[B]A\f[R] alone always equals decimal \f[B]10\f[R] and The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP -\f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]!\f[R] +.PP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP -\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +\f[B]=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] +\f[B]%=\f[R] \f[B]\[ha]=\f[R] +.PP +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. +\f[R] +.fi +.PP +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] +.PP +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -680,7 +771,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -724,62 +816,22 @@ command. An expression by itself is evaluated and printed, followed by a newline. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -875,9 +927,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -908,55 +960,74 @@ All of the functions below are available when the \f[B]-l\f[R] or The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1032,59 +1103,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1096,42 +1179,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1139,65 +1224,74 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator and the corresponding assignment operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator and the corresponding assignment -operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1227,7 +1321,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1247,7 +1341,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/EP.1.md b/manuals/bc/EP.1.md index 9a36b99bcb1c..62530a4a9744 100644 --- a/manuals/bc/EP.1.md +++ b/manuals/bc/EP.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -130,6 +130,12 @@ The following are the options that bc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Because bc(1) was built without support for prompts, this option is a no-op. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/H.1 b/manuals/bc/H.1 index fe9ac1556522..890630c4243b 100644 --- a/manuals/bc/H.1 +++ b/manuals/bc/H.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -53,210 +53,233 @@ the command line and executes them before reading from \f[B]stdin\f[R]. .SH OPTIONS .PP The following are the options that bc(1) accepts. -.TP +.PP \f[B]-g\f[R], \f[B]--global-stacks\f[R] -Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and -\f[B]seed\f[R] into stacks. -.RS .PP -This has the effect that a copy of the current value of all four are -pushed onto a stack for every function call, as well as popped when -every function returns. -This means that functions can assign to any and all of those globals -without worrying that the change will affect other functions. -Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply -printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this: +: Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], +and \f[B]seed\f[R] into stacks. .IP .nf \f[C] -define void output(x, b) { - obase=b - x -} -\f[R] -.fi -.PP +This has the effect that a copy of the current value of all four are pushed +onto a stack for every function call, as well as popped when every function +returns. This means that functions can assign to any and all of those +globals without worrying that the change will affect other functions. +Thus, a hypothetical function named **output(x,b)** that simply printed +**x** in base **b** could be written like this: + + define void output(x, b) { + obase=b + x + } + instead of like this: -.IP -.nf -\f[C] -define void output(x, b) { - auto c - c=obase - obase=b - x - obase=c -} -\f[R] -.fi -.PP + + define void output(x, b) { + auto c + c=obase + obase=b + x + obase=c + } + This makes writing functions much easier. -.PP -(\f[B]Note\f[R]: the function \f[B]output(x,b)\f[R] exists in the -extended math library. -See the \f[B]LIBRARY\f[R] section.) -.PP -However, since using this flag means that functions cannot set -\f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] -globally, functions that are made to do so cannot work anymore. -There are two possible use cases for that, and each has a solution. -.PP + +(**Note**: the function **output(x,b)** exists in the extended math library. + See the **LIBRARY** section.) + +However, since using this flag means that functions cannot set **ibase**, +**obase**, **scale**, or **seed** globally, functions that are made to do so +cannot work anymore. There are two possible use cases for that, and each has +a solution. + First, if a function is called on startup to turn bc(1) into a number converter, it is possible to replace that capability with various shell -aliases. -Examples: -.IP -.nf -\f[C] -alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] -alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] +aliases. Examples: + + alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] + alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] + +Second, if the purpose of a function is to set **ibase**, **obase**, +**scale**, or **seed** globally for any other purpose, it could be split +into one to four functions (based on how many globals it sets) and each of +those functions could return the desired value for a global. + +For functions that set **seed**, the value assigned to **seed** is not +propagated to parent functions. This means that the sequence of +pseudo-random numbers that they see will not be the same sequence of +pseudo-random numbers that any parent sees. This is only the case once +**seed** has been set. + +If a function desires to not affect the sequence of pseudo-random numbers +of its parents, but wants to use the same **seed**, it can use the following +line: + + seed = seed + +If the behavior of this option is desired for every run of bc(1), then users +could make sure to define **BC_ENV_ARGS** and include this option (see the +**ENVIRONMENT VARIABLES** section for more details). + +If **-s**, **-w**, or any equivalents are used, this option is ignored. + +This is a **non-portable extension**. \f[R] .fi .PP -Second, if the purpose of a function is to set \f[B]ibase\f[R], -\f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] globally for any -other purpose, it could be split into one to four functions (based on -how many globals it sets) and each of those functions could return the -desired value for a global. -.PP -For functions that set \f[B]seed\f[R], the value assigned to -\f[B]seed\f[R] is not propagated to parent functions. -This means that the sequence of pseudo-random numbers that they see will -not be the same sequence of pseudo-random numbers that any parent sees. -This is only the case once \f[B]seed\f[R] has been set. -.PP -If a function desires to not affect the sequence of pseudo-random -numbers of its parents, but wants to use the same \f[B]seed\f[R], it can -use the following line: -.IP -.nf -\f[C] -seed = seed -\f[R] -.fi -.PP -If the behavior of this option is desired for every run of bc(1), then -users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this -option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more -details). -.PP -If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option -is ignored. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library and the extended math library before -running any code, including any expressions or files specified on the -command line. -.RS .PP -To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library and the extended math +library before running any code, including any expressions or files +specified on the command line. +.IP +.nf +\f[C] +To learn what is in the libraries, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in \f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in bc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of bc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **read()** built-in function is called. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -313,7 +336,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -325,7 +348,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -497,7 +520,7 @@ This is a \f[B]non-portable extension\f[R]. .IP "15." 4 \f[B]irand(E)\f[R]: A pseudo-random integer between \f[B]0\f[R] (inclusive) and the value of \f[B]E\f[R] (exclusive). -If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[cq]s +If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[aq]s \f[I]scale\f[R] is not \f[B]0\f[R]), an error is raised, and bc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] remains unchanged. @@ -575,301 +598,377 @@ extension\f[R]. The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]$\f[R] -Type: Postfix -.RS .PP +: Type: Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **truncation** +\f[R] +.fi .PP -Description: \f[B]truncation\f[R] -.RE -.TP \f[B]\[at]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **set precision** +\f[R] +.fi .PP -Description: \f[B]set precision\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP \f[B]<<\f[R] \f[B]>>\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **shift left**, **shift right** +\f[R] +.fi .PP -Description: \f[B]shift left\f[R], \f[B]shift right\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP +.PP \f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]$\f[R] -The \f[B]truncation\f[R] operator returns a copy of the given expression -with all of its \f[I]scale\f[R] removed. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]truncation\f[R] operator returns a copy of the given +expression with all of its \f[I]scale\f[R] removed. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The \f[B]set precision\f[R] operator takes two expressions and returns a -copy of the first with its \f[I]scale\f[R] equal to the value of the +.PP +: The \f[B]set precision\f[R] operator takes two expressions and returns +a copy of the first with its \f[I]scale\f[R] equal to the value of the second expression. That could either mean that the number is returned without change (if the \f[I]scale\f[R] of the first expression matches the value of the second expression), extended (if it is less), or truncated (if it is more). -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]<<\f[R] -The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] and -\f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its +.PP +: The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] +and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the right. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]>>\f[R] -The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] +.PP +: The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the left. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. + +The **assignment** operators that correspond to operators that are +extensions are themselves **non-portable extensions**. +\f[R] +.fi .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP -The \f[B]assignment\f[R] operators that correspond to operators that are -extensions are themselves \f[B]non-portable extensions\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -895,7 +994,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -953,62 +1053,22 @@ Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -1104,9 +1164,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -1141,55 +1201,74 @@ are given. The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Extended Library .PP The extended library is \f[I]not\f[R] loaded when the @@ -1198,99 +1277,126 @@ options are given since they are not part of the library defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html). .PP The extended library is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p(x, y)\f[R] -Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if \f[B]y\f[R] -is not an integer, and returns the result to the current +.PP +: Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if +\f[B]y\f[R] is not an integer, and returns the result to the current \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +It is an error if **y** is negative and **x** is **0**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -It is an error if \f[B]y\f[R] is negative and \f[B]x\f[R] is -\f[B]0\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round half away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). -.TP +.PP \f[B]ceil(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero). -.TP +.PP \f[B]f(x)\f[R] -Returns the factorial of the truncated absolute value of \f[B]x\f[R]. -.TP +.PP +: Returns the factorial of the truncated absolute value of \f[B]x\f[R]. +.PP \f[B]perm(n, k)\f[R] -Returns the permutation of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the permutation of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]comb(n, k)\f[R] -Returns the combination of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the combination of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]l2(x)\f[R] -Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l10(x)\f[R] -Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]log(x, b)\f[R] -Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]cbrt(x)\f[R] -Returns the cube root of \f[B]x\f[R]. -.TP +.PP +: Returns the cube root of \f[B]x\f[R]. +.PP \f[B]root(x, n)\f[R] -Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and returns -the \f[B]r\f[R]th root of \f[B]x\f[R] to the current \f[B]scale\f[R]. -.RS .PP -If \f[B]r\f[R] is \f[B]0\f[R] or negative, this raises an error and -causes bc(1) to reset (see the \f[B]RESET\f[R] section). -It also raises an error and causes bc(1) to reset if \f[B]r\f[R] is even -and \f[B]x\f[R] is negative. -.RE -.TP +: Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and +returns the \f[B]r\f[R]th root of \f[B]x\f[R] to the current +\f[B]scale\f[R]. +.IP +.nf +\f[C] +If **r** is **0** or negative, this raises an error and causes bc(1) to +reset (see the **RESET** section). It also raises an error and causes bc(1) +to reset if **r** is even and **x** is negative. +\f[R] +.fi +.PP \f[B]pi(p)\f[R] -Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]t(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1303,60 +1409,75 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]sin(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]s(x)\f[R]. +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **s(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]cos(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]c(x)\f[R]. +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **c(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]tan(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -If \f[B]x\f[R] is equal to \f[B]1\f[R] or \f[B]-1\f[R], this raises an -error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +If **x** is equal to **1** or **-1**, this raises an error and causes bc(1) +to reset (see the **RESET** section). + +This is an alias of **t(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is an alias of \f[B]t(x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is an alias of \f[B]a(x)\f[R]. +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is an alias of **a(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1369,302 +1490,367 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is an alias of **a2(y, x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is an alias of \f[B]a2(y, x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r2d(x)\f[R] -Converts \f[B]x\f[R] from radians to degrees and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from radians to degrees and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]d2r(x)\f[R] -Converts \f[B]x\f[R] from degrees to radians and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from degrees to radians and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]frand(p)\f[R] -Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and +.PP +: Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R] (exclusive) with the number of decimal digits after the decimal point equal to the truncated absolute value of \f[B]p\f[R]. If \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]. If \f[B]p\f[R] is \f[B]0\f[R], then \f[B]0\f[R] is returned, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.TP +.PP \f[B]ifrand(i, p)\f[R] -Generates a pseudo-random number that is between \f[B]0\f[R] (inclusive) -and the truncated absolute value of \f[B]i\f[R] (exclusive) with the -number of decimal digits after the decimal point equal to the truncated -absolute value of \f[B]p\f[R]. +.PP +: Generates a pseudo-random number that is between \f[B]0\f[R] +(inclusive) and the truncated absolute value of \f[B]i\f[R] (exclusive) +with the number of decimal digits after the decimal point equal to the +truncated absolute value of \f[B]p\f[R]. If the absolute value of \f[B]i\f[R] is greater than or equal to \f[B]2\f[R], and \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]; otherwise, \f[B]0\f[R] is returned and \f[B]seed\f[R] is not changed. -.TP +.PP \f[B]srand(x)\f[R] -Returns \f[B]x\f[R] with its sign flipped with probability +.PP +: Returns \f[B]x\f[R] with its sign flipped with probability \f[B]0.5\f[R]. In other words, it randomizes the sign of \f[B]x\f[R]. -.TP +.PP \f[B]brand()\f[R] -Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). -.TP +.PP +: Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). +.PP \f[B]ubytes(x)\f[R] -Returns the numbers of unsigned integer bytes required to hold the +.PP +: Returns the numbers of unsigned integer bytes required to hold the truncated absolute value of \f[B]x\f[R]. -.TP +.PP \f[B]sbytes(x)\f[R] -Returns the numbers of signed, two\[cq]s-complement integer bytes +.PP +: Returns the numbers of signed, two\[aq]s-complement integer bytes required to hold the truncated value of \f[B]x\f[R]. -.TP +.PP \f[B]hex(x)\f[R] -Outputs the hexadecimal (base \f[B]16\f[R]) representation of +.PP +: Outputs the hexadecimal (base \f[B]16\f[R]) representation of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary(x)\f[R] -Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]output(x, b)\f[R] -Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]uint(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in as few power of two bytes as possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or is negative, an error message is printed +instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or is negative, an error message is -printed instead, but bc(1) is not reset (see the \f[B]RESET\f[R] -section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in as few power of two bytes as -possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in as few power of two bytes +as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, an error message is printed instead, but bc(1) +is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, an error message is printed instead, -but bc(1) is not reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uintn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **n** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]n\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]intn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **n** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]n\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **1** byte, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]1\f[R] byte, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **1** byte, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]1\f[R] byte, an -error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **2** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]2\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **2** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]2\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **4** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]4\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **4** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]4\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **8** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]8\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **8** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]8\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]hex_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in hexadecimal using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in binary using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in the current \f[B]obase\f[R] (see the \f[B]SYNTAX\f[R] section) using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_byte(x, i)\f[R] -Outputs byte \f[B]i\f[R] of the truncated absolute value of \f[B]x\f[R], -where \f[B]0\f[R] is the least significant byte and \f[B]number_of_bytes -- 1\f[R] is the most significant byte. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE +: Outputs byte \f[B]i\f[R] of the truncated absolute value of +\f[B]x\f[R], where \f[B]0\f[R] is the least significant byte and +\f[B]number_of_bytes - 1\f[R] is the most significant byte. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1768,64 +1954,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]rand()\f[R] +.PP +: The maximum integer (inclusive) returned by the \f[B]rand()\f[R] operand. Set at \f[B]2\[ha]BC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1837,42 +2036,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1880,68 +2081,76 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**\[rs]<\[rs]<**), and right shift (**\[rs]>\[rs]>**) +operators and their corresponding assignment operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]<<\f[R]), and right shift (\f[B]>>\f[R]) operators and their -corresponding assignment operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1971,7 +2180,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP The prompt is enabled in TTY mode. .PP @@ -1988,7 +2197,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/H.1.md b/manuals/bc/H.1.md index 5ba65ba1f5d6..57a753a417e6 100644 --- a/manuals/bc/H.1.md +++ b/manuals/bc/H.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -139,13 +139,27 @@ The following are the options that bc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in **BC_ENV_ARGS** (see the **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in bc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of bc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **read()** built-in function is called. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/HN.1 b/manuals/bc/HN.1 index fe6043eb69d1..97965d7a8868 100644 --- a/manuals/bc/HN.1 +++ b/manuals/bc/HN.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -53,210 +53,233 @@ the command line and executes them before reading from \f[B]stdin\f[R]. .SH OPTIONS .PP The following are the options that bc(1) accepts. -.TP +.PP \f[B]-g\f[R], \f[B]--global-stacks\f[R] -Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and -\f[B]seed\f[R] into stacks. -.RS .PP -This has the effect that a copy of the current value of all four are -pushed onto a stack for every function call, as well as popped when -every function returns. -This means that functions can assign to any and all of those globals -without worrying that the change will affect other functions. -Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply -printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this: +: Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], +and \f[B]seed\f[R] into stacks. .IP .nf \f[C] -define void output(x, b) { - obase=b - x -} -\f[R] -.fi -.PP +This has the effect that a copy of the current value of all four are pushed +onto a stack for every function call, as well as popped when every function +returns. This means that functions can assign to any and all of those +globals without worrying that the change will affect other functions. +Thus, a hypothetical function named **output(x,b)** that simply printed +**x** in base **b** could be written like this: + + define void output(x, b) { + obase=b + x + } + instead of like this: -.IP -.nf -\f[C] -define void output(x, b) { - auto c - c=obase - obase=b - x - obase=c -} -\f[R] -.fi -.PP + + define void output(x, b) { + auto c + c=obase + obase=b + x + obase=c + } + This makes writing functions much easier. -.PP -(\f[B]Note\f[R]: the function \f[B]output(x,b)\f[R] exists in the -extended math library. -See the \f[B]LIBRARY\f[R] section.) -.PP -However, since using this flag means that functions cannot set -\f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] -globally, functions that are made to do so cannot work anymore. -There are two possible use cases for that, and each has a solution. -.PP + +(**Note**: the function **output(x,b)** exists in the extended math library. + See the **LIBRARY** section.) + +However, since using this flag means that functions cannot set **ibase**, +**obase**, **scale**, or **seed** globally, functions that are made to do so +cannot work anymore. There are two possible use cases for that, and each has +a solution. + First, if a function is called on startup to turn bc(1) into a number converter, it is possible to replace that capability with various shell -aliases. -Examples: -.IP -.nf -\f[C] -alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] -alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] +aliases. Examples: + + alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] + alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] + +Second, if the purpose of a function is to set **ibase**, **obase**, +**scale**, or **seed** globally for any other purpose, it could be split +into one to four functions (based on how many globals it sets) and each of +those functions could return the desired value for a global. + +For functions that set **seed**, the value assigned to **seed** is not +propagated to parent functions. This means that the sequence of +pseudo-random numbers that they see will not be the same sequence of +pseudo-random numbers that any parent sees. This is only the case once +**seed** has been set. + +If a function desires to not affect the sequence of pseudo-random numbers +of its parents, but wants to use the same **seed**, it can use the following +line: + + seed = seed + +If the behavior of this option is desired for every run of bc(1), then users +could make sure to define **BC_ENV_ARGS** and include this option (see the +**ENVIRONMENT VARIABLES** section for more details). + +If **-s**, **-w**, or any equivalents are used, this option is ignored. + +This is a **non-portable extension**. \f[R] .fi .PP -Second, if the purpose of a function is to set \f[B]ibase\f[R], -\f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] globally for any -other purpose, it could be split into one to four functions (based on -how many globals it sets) and each of those functions could return the -desired value for a global. -.PP -For functions that set \f[B]seed\f[R], the value assigned to -\f[B]seed\f[R] is not propagated to parent functions. -This means that the sequence of pseudo-random numbers that they see will -not be the same sequence of pseudo-random numbers that any parent sees. -This is only the case once \f[B]seed\f[R] has been set. -.PP -If a function desires to not affect the sequence of pseudo-random -numbers of its parents, but wants to use the same \f[B]seed\f[R], it can -use the following line: -.IP -.nf -\f[C] -seed = seed -\f[R] -.fi -.PP -If the behavior of this option is desired for every run of bc(1), then -users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this -option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more -details). -.PP -If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option -is ignored. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library and the extended math library before -running any code, including any expressions or files specified on the -command line. -.RS .PP -To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library and the extended math +library before running any code, including any expressions or files +specified on the command line. +.IP +.nf +\f[C] +To learn what is in the libraries, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in \f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in bc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of bc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **read()** built-in function is called. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -313,7 +336,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -325,7 +348,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -497,7 +520,7 @@ This is a \f[B]non-portable extension\f[R]. .IP "15." 4 \f[B]irand(E)\f[R]: A pseudo-random integer between \f[B]0\f[R] (inclusive) and the value of \f[B]E\f[R] (exclusive). -If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[cq]s +If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[aq]s \f[I]scale\f[R] is not \f[B]0\f[R]), an error is raised, and bc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] remains unchanged. @@ -575,301 +598,377 @@ extension\f[R]. The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]$\f[R] -Type: Postfix -.RS .PP +: Type: Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **truncation** +\f[R] +.fi .PP -Description: \f[B]truncation\f[R] -.RE -.TP \f[B]\[at]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **set precision** +\f[R] +.fi .PP -Description: \f[B]set precision\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP \f[B]<<\f[R] \f[B]>>\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **shift left**, **shift right** +\f[R] +.fi .PP -Description: \f[B]shift left\f[R], \f[B]shift right\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP +.PP \f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]$\f[R] -The \f[B]truncation\f[R] operator returns a copy of the given expression -with all of its \f[I]scale\f[R] removed. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]truncation\f[R] operator returns a copy of the given +expression with all of its \f[I]scale\f[R] removed. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The \f[B]set precision\f[R] operator takes two expressions and returns a -copy of the first with its \f[I]scale\f[R] equal to the value of the +.PP +: The \f[B]set precision\f[R] operator takes two expressions and returns +a copy of the first with its \f[I]scale\f[R] equal to the value of the second expression. That could either mean that the number is returned without change (if the \f[I]scale\f[R] of the first expression matches the value of the second expression), extended (if it is less), or truncated (if it is more). -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]<<\f[R] -The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] and -\f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its +.PP +: The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] +and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the right. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]>>\f[R] -The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] +.PP +: The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the left. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. + +The **assignment** operators that correspond to operators that are +extensions are themselves **non-portable extensions**. +\f[R] +.fi .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP -The \f[B]assignment\f[R] operators that correspond to operators that are -extensions are themselves \f[B]non-portable extensions\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -895,7 +994,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -953,62 +1053,22 @@ Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -1104,9 +1164,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -1141,55 +1201,74 @@ are given. The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Extended Library .PP The extended library is \f[I]not\f[R] loaded when the @@ -1198,99 +1277,126 @@ options are given since they are not part of the library defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html). .PP The extended library is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p(x, y)\f[R] -Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if \f[B]y\f[R] -is not an integer, and returns the result to the current +.PP +: Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if +\f[B]y\f[R] is not an integer, and returns the result to the current \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +It is an error if **y** is negative and **x** is **0**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -It is an error if \f[B]y\f[R] is negative and \f[B]x\f[R] is -\f[B]0\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round half away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). -.TP +.PP \f[B]ceil(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero). -.TP +.PP \f[B]f(x)\f[R] -Returns the factorial of the truncated absolute value of \f[B]x\f[R]. -.TP +.PP +: Returns the factorial of the truncated absolute value of \f[B]x\f[R]. +.PP \f[B]perm(n, k)\f[R] -Returns the permutation of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the permutation of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]comb(n, k)\f[R] -Returns the combination of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the combination of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]l2(x)\f[R] -Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l10(x)\f[R] -Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]log(x, b)\f[R] -Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]cbrt(x)\f[R] -Returns the cube root of \f[B]x\f[R]. -.TP +.PP +: Returns the cube root of \f[B]x\f[R]. +.PP \f[B]root(x, n)\f[R] -Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and returns -the \f[B]r\f[R]th root of \f[B]x\f[R] to the current \f[B]scale\f[R]. -.RS .PP -If \f[B]r\f[R] is \f[B]0\f[R] or negative, this raises an error and -causes bc(1) to reset (see the \f[B]RESET\f[R] section). -It also raises an error and causes bc(1) to reset if \f[B]r\f[R] is even -and \f[B]x\f[R] is negative. -.RE -.TP +: Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and +returns the \f[B]r\f[R]th root of \f[B]x\f[R] to the current +\f[B]scale\f[R]. +.IP +.nf +\f[C] +If **r** is **0** or negative, this raises an error and causes bc(1) to +reset (see the **RESET** section). It also raises an error and causes bc(1) +to reset if **r** is even and **x** is negative. +\f[R] +.fi +.PP \f[B]pi(p)\f[R] -Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]t(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1303,60 +1409,75 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]sin(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]s(x)\f[R]. +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **s(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]cos(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]c(x)\f[R]. +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **c(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]tan(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -If \f[B]x\f[R] is equal to \f[B]1\f[R] or \f[B]-1\f[R], this raises an -error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +If **x** is equal to **1** or **-1**, this raises an error and causes bc(1) +to reset (see the **RESET** section). + +This is an alias of **t(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is an alias of \f[B]t(x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is an alias of \f[B]a(x)\f[R]. +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is an alias of **a(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1369,302 +1490,367 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is an alias of **a2(y, x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is an alias of \f[B]a2(y, x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r2d(x)\f[R] -Converts \f[B]x\f[R] from radians to degrees and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from radians to degrees and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]d2r(x)\f[R] -Converts \f[B]x\f[R] from degrees to radians and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from degrees to radians and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]frand(p)\f[R] -Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and +.PP +: Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R] (exclusive) with the number of decimal digits after the decimal point equal to the truncated absolute value of \f[B]p\f[R]. If \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]. If \f[B]p\f[R] is \f[B]0\f[R], then \f[B]0\f[R] is returned, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.TP +.PP \f[B]ifrand(i, p)\f[R] -Generates a pseudo-random number that is between \f[B]0\f[R] (inclusive) -and the truncated absolute value of \f[B]i\f[R] (exclusive) with the -number of decimal digits after the decimal point equal to the truncated -absolute value of \f[B]p\f[R]. +.PP +: Generates a pseudo-random number that is between \f[B]0\f[R] +(inclusive) and the truncated absolute value of \f[B]i\f[R] (exclusive) +with the number of decimal digits after the decimal point equal to the +truncated absolute value of \f[B]p\f[R]. If the absolute value of \f[B]i\f[R] is greater than or equal to \f[B]2\f[R], and \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]; otherwise, \f[B]0\f[R] is returned and \f[B]seed\f[R] is not changed. -.TP +.PP \f[B]srand(x)\f[R] -Returns \f[B]x\f[R] with its sign flipped with probability +.PP +: Returns \f[B]x\f[R] with its sign flipped with probability \f[B]0.5\f[R]. In other words, it randomizes the sign of \f[B]x\f[R]. -.TP +.PP \f[B]brand()\f[R] -Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). -.TP +.PP +: Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). +.PP \f[B]ubytes(x)\f[R] -Returns the numbers of unsigned integer bytes required to hold the +.PP +: Returns the numbers of unsigned integer bytes required to hold the truncated absolute value of \f[B]x\f[R]. -.TP +.PP \f[B]sbytes(x)\f[R] -Returns the numbers of signed, two\[cq]s-complement integer bytes +.PP +: Returns the numbers of signed, two\[aq]s-complement integer bytes required to hold the truncated value of \f[B]x\f[R]. -.TP +.PP \f[B]hex(x)\f[R] -Outputs the hexadecimal (base \f[B]16\f[R]) representation of +.PP +: Outputs the hexadecimal (base \f[B]16\f[R]) representation of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary(x)\f[R] -Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]output(x, b)\f[R] -Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]uint(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in as few power of two bytes as possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or is negative, an error message is printed +instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or is negative, an error message is -printed instead, but bc(1) is not reset (see the \f[B]RESET\f[R] -section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in as few power of two bytes as -possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in as few power of two bytes +as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, an error message is printed instead, but bc(1) +is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, an error message is printed instead, -but bc(1) is not reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uintn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **n** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]n\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]intn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **n** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]n\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **1** byte, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]1\f[R] byte, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **1** byte, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]1\f[R] byte, an -error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **2** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]2\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **2** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]2\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **4** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]4\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **4** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]4\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **8** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]8\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **8** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]8\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]hex_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in hexadecimal using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in binary using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in the current \f[B]obase\f[R] (see the \f[B]SYNTAX\f[R] section) using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_byte(x, i)\f[R] -Outputs byte \f[B]i\f[R] of the truncated absolute value of \f[B]x\f[R], -where \f[B]0\f[R] is the least significant byte and \f[B]number_of_bytes -- 1\f[R] is the most significant byte. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE +: Outputs byte \f[B]i\f[R] of the truncated absolute value of +\f[B]x\f[R], where \f[B]0\f[R] is the least significant byte and +\f[B]number_of_bytes - 1\f[R] is the most significant byte. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1768,64 +1954,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]rand()\f[R] +.PP +: The maximum integer (inclusive) returned by the \f[B]rand()\f[R] operand. Set at \f[B]2\[ha]BC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1837,42 +2036,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1880,68 +2081,76 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**\[rs]<\[rs]<**), and right shift (**\[rs]>\[rs]>**) +operators and their corresponding assignment operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]<<\f[R]), and right shift (\f[B]>>\f[R]) operators and their -corresponding assignment operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1971,7 +2180,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP The prompt is enabled in TTY mode. .PP @@ -1988,7 +2197,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/HN.1.md b/manuals/bc/HN.1.md index adf1ffcc29fb..c81f7adcd7e3 100644 --- a/manuals/bc/HN.1.md +++ b/manuals/bc/HN.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -139,13 +139,27 @@ The following are the options that bc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in **BC_ENV_ARGS** (see the **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in bc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of bc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **read()** built-in function is called. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/HNP.1 b/manuals/bc/HNP.1 index f407050515b2..e51c6373e732 100644 --- a/manuals/bc/HNP.1 +++ b/manuals/bc/HNP.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -53,205 +53,219 @@ the command line and executes them before reading from \f[B]stdin\f[R]. .SH OPTIONS .PP The following are the options that bc(1) accepts. -.TP +.PP \f[B]-g\f[R], \f[B]--global-stacks\f[R] -Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and -\f[B]seed\f[R] into stacks. -.RS .PP -This has the effect that a copy of the current value of all four are -pushed onto a stack for every function call, as well as popped when -every function returns. -This means that functions can assign to any and all of those globals -without worrying that the change will affect other functions. -Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply -printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this: +: Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], +and \f[B]seed\f[R] into stacks. .IP .nf \f[C] -define void output(x, b) { - obase=b - x -} -\f[R] -.fi -.PP +This has the effect that a copy of the current value of all four are pushed +onto a stack for every function call, as well as popped when every function +returns. This means that functions can assign to any and all of those +globals without worrying that the change will affect other functions. +Thus, a hypothetical function named **output(x,b)** that simply printed +**x** in base **b** could be written like this: + + define void output(x, b) { + obase=b + x + } + instead of like this: -.IP -.nf -\f[C] -define void output(x, b) { - auto c - c=obase - obase=b - x - obase=c -} -\f[R] -.fi -.PP + + define void output(x, b) { + auto c + c=obase + obase=b + x + obase=c + } + This makes writing functions much easier. -.PP -(\f[B]Note\f[R]: the function \f[B]output(x,b)\f[R] exists in the -extended math library. -See the \f[B]LIBRARY\f[R] section.) -.PP -However, since using this flag means that functions cannot set -\f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] -globally, functions that are made to do so cannot work anymore. -There are two possible use cases for that, and each has a solution. -.PP + +(**Note**: the function **output(x,b)** exists in the extended math library. + See the **LIBRARY** section.) + +However, since using this flag means that functions cannot set **ibase**, +**obase**, **scale**, or **seed** globally, functions that are made to do so +cannot work anymore. There are two possible use cases for that, and each has +a solution. + First, if a function is called on startup to turn bc(1) into a number converter, it is possible to replace that capability with various shell -aliases. -Examples: -.IP -.nf -\f[C] -alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] -alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] +aliases. Examples: + + alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] + alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] + +Second, if the purpose of a function is to set **ibase**, **obase**, +**scale**, or **seed** globally for any other purpose, it could be split +into one to four functions (based on how many globals it sets) and each of +those functions could return the desired value for a global. + +For functions that set **seed**, the value assigned to **seed** is not +propagated to parent functions. This means that the sequence of +pseudo-random numbers that they see will not be the same sequence of +pseudo-random numbers that any parent sees. This is only the case once +**seed** has been set. + +If a function desires to not affect the sequence of pseudo-random numbers +of its parents, but wants to use the same **seed**, it can use the following +line: + + seed = seed + +If the behavior of this option is desired for every run of bc(1), then users +could make sure to define **BC_ENV_ARGS** and include this option (see the +**ENVIRONMENT VARIABLES** section for more details). + +If **-s**, **-w**, or any equivalents are used, this option is ignored. + +This is a **non-portable extension**. \f[R] .fi .PP -Second, if the purpose of a function is to set \f[B]ibase\f[R], -\f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] globally for any -other purpose, it could be split into one to four functions (based on -how many globals it sets) and each of those functions could return the -desired value for a global. -.PP -For functions that set \f[B]seed\f[R], the value assigned to -\f[B]seed\f[R] is not propagated to parent functions. -This means that the sequence of pseudo-random numbers that they see will -not be the same sequence of pseudo-random numbers that any parent sees. -This is only the case once \f[B]seed\f[R] has been set. -.PP -If a function desires to not affect the sequence of pseudo-random -numbers of its parents, but wants to use the same \f[B]seed\f[R], it can -use the following line: -.IP -.nf -\f[C] -seed = seed -\f[R] -.fi -.PP -If the behavior of this option is desired for every run of bc(1), then -users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this -option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more -details). -.PP -If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option -is ignored. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library and the extended math library before -running any code, including any expressions or files specified on the -command line. -.RS .PP -To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library and the extended math +library before running any code, including any expressions or files +specified on the command line. +.IP +.nf +\f[C] +To learn what is in the libraries, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Because bc(1) was built without support for prompts, this option is a +no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -308,7 +322,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -320,7 +334,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -492,7 +506,7 @@ This is a \f[B]non-portable extension\f[R]. .IP "15." 4 \f[B]irand(E)\f[R]: A pseudo-random integer between \f[B]0\f[R] (inclusive) and the value of \f[B]E\f[R] (exclusive). -If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[cq]s +If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[aq]s \f[I]scale\f[R] is not \f[B]0\f[R]), an error is raised, and bc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] remains unchanged. @@ -570,301 +584,377 @@ extension\f[R]. The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]$\f[R] -Type: Postfix -.RS .PP +: Type: Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **truncation** +\f[R] +.fi .PP -Description: \f[B]truncation\f[R] -.RE -.TP \f[B]\[at]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **set precision** +\f[R] +.fi .PP -Description: \f[B]set precision\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP \f[B]<<\f[R] \f[B]>>\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **shift left**, **shift right** +\f[R] +.fi .PP -Description: \f[B]shift left\f[R], \f[B]shift right\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP +.PP \f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]$\f[R] -The \f[B]truncation\f[R] operator returns a copy of the given expression -with all of its \f[I]scale\f[R] removed. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]truncation\f[R] operator returns a copy of the given +expression with all of its \f[I]scale\f[R] removed. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The \f[B]set precision\f[R] operator takes two expressions and returns a -copy of the first with its \f[I]scale\f[R] equal to the value of the +.PP +: The \f[B]set precision\f[R] operator takes two expressions and returns +a copy of the first with its \f[I]scale\f[R] equal to the value of the second expression. That could either mean that the number is returned without change (if the \f[I]scale\f[R] of the first expression matches the value of the second expression), extended (if it is less), or truncated (if it is more). -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]<<\f[R] -The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] and -\f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its +.PP +: The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] +and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the right. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]>>\f[R] -The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] +.PP +: The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the left. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. + +The **assignment** operators that correspond to operators that are +extensions are themselves **non-portable extensions**. +\f[R] +.fi .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP -The \f[B]assignment\f[R] operators that correspond to operators that are -extensions are themselves \f[B]non-portable extensions\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -890,7 +980,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -948,62 +1039,22 @@ Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -1099,9 +1150,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -1136,55 +1187,74 @@ are given. The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Extended Library .PP The extended library is \f[I]not\f[R] loaded when the @@ -1193,99 +1263,126 @@ options are given since they are not part of the library defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html). .PP The extended library is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p(x, y)\f[R] -Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if \f[B]y\f[R] -is not an integer, and returns the result to the current +.PP +: Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if +\f[B]y\f[R] is not an integer, and returns the result to the current \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +It is an error if **y** is negative and **x** is **0**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -It is an error if \f[B]y\f[R] is negative and \f[B]x\f[R] is -\f[B]0\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round half away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). -.TP +.PP \f[B]ceil(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero). -.TP +.PP \f[B]f(x)\f[R] -Returns the factorial of the truncated absolute value of \f[B]x\f[R]. -.TP +.PP +: Returns the factorial of the truncated absolute value of \f[B]x\f[R]. +.PP \f[B]perm(n, k)\f[R] -Returns the permutation of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the permutation of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]comb(n, k)\f[R] -Returns the combination of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the combination of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]l2(x)\f[R] -Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l10(x)\f[R] -Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]log(x, b)\f[R] -Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]cbrt(x)\f[R] -Returns the cube root of \f[B]x\f[R]. -.TP +.PP +: Returns the cube root of \f[B]x\f[R]. +.PP \f[B]root(x, n)\f[R] -Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and returns -the \f[B]r\f[R]th root of \f[B]x\f[R] to the current \f[B]scale\f[R]. -.RS .PP -If \f[B]r\f[R] is \f[B]0\f[R] or negative, this raises an error and -causes bc(1) to reset (see the \f[B]RESET\f[R] section). -It also raises an error and causes bc(1) to reset if \f[B]r\f[R] is even -and \f[B]x\f[R] is negative. -.RE -.TP +: Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and +returns the \f[B]r\f[R]th root of \f[B]x\f[R] to the current +\f[B]scale\f[R]. +.IP +.nf +\f[C] +If **r** is **0** or negative, this raises an error and causes bc(1) to +reset (see the **RESET** section). It also raises an error and causes bc(1) +to reset if **r** is even and **x** is negative. +\f[R] +.fi +.PP \f[B]pi(p)\f[R] -Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]t(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1298,60 +1395,75 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]sin(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]s(x)\f[R]. +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **s(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]cos(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]c(x)\f[R]. +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **c(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]tan(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -If \f[B]x\f[R] is equal to \f[B]1\f[R] or \f[B]-1\f[R], this raises an -error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +If **x** is equal to **1** or **-1**, this raises an error and causes bc(1) +to reset (see the **RESET** section). + +This is an alias of **t(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is an alias of \f[B]t(x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is an alias of \f[B]a(x)\f[R]. +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is an alias of **a(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1364,302 +1476,367 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is an alias of **a2(y, x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is an alias of \f[B]a2(y, x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r2d(x)\f[R] -Converts \f[B]x\f[R] from radians to degrees and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from radians to degrees and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]d2r(x)\f[R] -Converts \f[B]x\f[R] from degrees to radians and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from degrees to radians and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]frand(p)\f[R] -Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and +.PP +: Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R] (exclusive) with the number of decimal digits after the decimal point equal to the truncated absolute value of \f[B]p\f[R]. If \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]. If \f[B]p\f[R] is \f[B]0\f[R], then \f[B]0\f[R] is returned, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.TP +.PP \f[B]ifrand(i, p)\f[R] -Generates a pseudo-random number that is between \f[B]0\f[R] (inclusive) -and the truncated absolute value of \f[B]i\f[R] (exclusive) with the -number of decimal digits after the decimal point equal to the truncated -absolute value of \f[B]p\f[R]. +.PP +: Generates a pseudo-random number that is between \f[B]0\f[R] +(inclusive) and the truncated absolute value of \f[B]i\f[R] (exclusive) +with the number of decimal digits after the decimal point equal to the +truncated absolute value of \f[B]p\f[R]. If the absolute value of \f[B]i\f[R] is greater than or equal to \f[B]2\f[R], and \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]; otherwise, \f[B]0\f[R] is returned and \f[B]seed\f[R] is not changed. -.TP +.PP \f[B]srand(x)\f[R] -Returns \f[B]x\f[R] with its sign flipped with probability +.PP +: Returns \f[B]x\f[R] with its sign flipped with probability \f[B]0.5\f[R]. In other words, it randomizes the sign of \f[B]x\f[R]. -.TP +.PP \f[B]brand()\f[R] -Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). -.TP +.PP +: Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). +.PP \f[B]ubytes(x)\f[R] -Returns the numbers of unsigned integer bytes required to hold the +.PP +: Returns the numbers of unsigned integer bytes required to hold the truncated absolute value of \f[B]x\f[R]. -.TP +.PP \f[B]sbytes(x)\f[R] -Returns the numbers of signed, two\[cq]s-complement integer bytes +.PP +: Returns the numbers of signed, two\[aq]s-complement integer bytes required to hold the truncated value of \f[B]x\f[R]. -.TP +.PP \f[B]hex(x)\f[R] -Outputs the hexadecimal (base \f[B]16\f[R]) representation of +.PP +: Outputs the hexadecimal (base \f[B]16\f[R]) representation of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary(x)\f[R] -Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]output(x, b)\f[R] -Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]uint(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in as few power of two bytes as possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or is negative, an error message is printed +instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or is negative, an error message is -printed instead, but bc(1) is not reset (see the \f[B]RESET\f[R] -section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in as few power of two bytes as -possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in as few power of two bytes +as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, an error message is printed instead, but bc(1) +is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, an error message is printed instead, -but bc(1) is not reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uintn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **n** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]n\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]intn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **n** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]n\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **1** byte, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]1\f[R] byte, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **1** byte, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]1\f[R] byte, an -error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **2** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]2\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **2** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]2\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **4** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]4\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **4** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]4\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **8** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]8\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **8** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]8\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]hex_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in hexadecimal using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in binary using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in the current \f[B]obase\f[R] (see the \f[B]SYNTAX\f[R] section) using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_byte(x, i)\f[R] -Outputs byte \f[B]i\f[R] of the truncated absolute value of \f[B]x\f[R], -where \f[B]0\f[R] is the least significant byte and \f[B]number_of_bytes -- 1\f[R] is the most significant byte. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE +: Outputs byte \f[B]i\f[R] of the truncated absolute value of +\f[B]x\f[R], where \f[B]0\f[R] is the least significant byte and +\f[B]number_of_bytes - 1\f[R] is the most significant byte. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1763,64 +1940,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]rand()\f[R] +.PP +: The maximum integer (inclusive) returned by the \f[B]rand()\f[R] operand. Set at \f[B]2\[ha]BC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1832,42 +2022,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1875,68 +2067,76 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**\[rs]<\[rs]<**), and right shift (**\[rs]>\[rs]>**) +operators and their corresponding assignment operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]<<\f[R]), and right shift (\f[B]>>\f[R]) operators and their -corresponding assignment operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1966,7 +2166,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is different from interactive mode because interactive mode is required in the bc(1) @@ -1981,7 +2181,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/HNP.1.md b/manuals/bc/HNP.1.md index cd6d2c4836e9..365ee36926a1 100644 --- a/manuals/bc/HNP.1.md +++ b/manuals/bc/HNP.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -142,6 +142,12 @@ The following are the options that bc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Because bc(1) was built without support for prompts, this option is a no-op. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/HP.1 b/manuals/bc/HP.1 index 33293307f8f3..71c79623abad 100644 --- a/manuals/bc/HP.1 +++ b/manuals/bc/HP.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -53,205 +53,219 @@ the command line and executes them before reading from \f[B]stdin\f[R]. .SH OPTIONS .PP The following are the options that bc(1) accepts. -.TP +.PP \f[B]-g\f[R], \f[B]--global-stacks\f[R] -Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and -\f[B]seed\f[R] into stacks. -.RS .PP -This has the effect that a copy of the current value of all four are -pushed onto a stack for every function call, as well as popped when -every function returns. -This means that functions can assign to any and all of those globals -without worrying that the change will affect other functions. -Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply -printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this: +: Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], +and \f[B]seed\f[R] into stacks. .IP .nf \f[C] -define void output(x, b) { - obase=b - x -} -\f[R] -.fi -.PP +This has the effect that a copy of the current value of all four are pushed +onto a stack for every function call, as well as popped when every function +returns. This means that functions can assign to any and all of those +globals without worrying that the change will affect other functions. +Thus, a hypothetical function named **output(x,b)** that simply printed +**x** in base **b** could be written like this: + + define void output(x, b) { + obase=b + x + } + instead of like this: -.IP -.nf -\f[C] -define void output(x, b) { - auto c - c=obase - obase=b - x - obase=c -} -\f[R] -.fi -.PP + + define void output(x, b) { + auto c + c=obase + obase=b + x + obase=c + } + This makes writing functions much easier. -.PP -(\f[B]Note\f[R]: the function \f[B]output(x,b)\f[R] exists in the -extended math library. -See the \f[B]LIBRARY\f[R] section.) -.PP -However, since using this flag means that functions cannot set -\f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] -globally, functions that are made to do so cannot work anymore. -There are two possible use cases for that, and each has a solution. -.PP + +(**Note**: the function **output(x,b)** exists in the extended math library. + See the **LIBRARY** section.) + +However, since using this flag means that functions cannot set **ibase**, +**obase**, **scale**, or **seed** globally, functions that are made to do so +cannot work anymore. There are two possible use cases for that, and each has +a solution. + First, if a function is called on startup to turn bc(1) into a number converter, it is possible to replace that capability with various shell -aliases. -Examples: -.IP -.nf -\f[C] -alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] -alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] +aliases. Examples: + + alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] + alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] + +Second, if the purpose of a function is to set **ibase**, **obase**, +**scale**, or **seed** globally for any other purpose, it could be split +into one to four functions (based on how many globals it sets) and each of +those functions could return the desired value for a global. + +For functions that set **seed**, the value assigned to **seed** is not +propagated to parent functions. This means that the sequence of +pseudo-random numbers that they see will not be the same sequence of +pseudo-random numbers that any parent sees. This is only the case once +**seed** has been set. + +If a function desires to not affect the sequence of pseudo-random numbers +of its parents, but wants to use the same **seed**, it can use the following +line: + + seed = seed + +If the behavior of this option is desired for every run of bc(1), then users +could make sure to define **BC_ENV_ARGS** and include this option (see the +**ENVIRONMENT VARIABLES** section for more details). + +If **-s**, **-w**, or any equivalents are used, this option is ignored. + +This is a **non-portable extension**. \f[R] .fi .PP -Second, if the purpose of a function is to set \f[B]ibase\f[R], -\f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] globally for any -other purpose, it could be split into one to four functions (based on -how many globals it sets) and each of those functions could return the -desired value for a global. -.PP -For functions that set \f[B]seed\f[R], the value assigned to -\f[B]seed\f[R] is not propagated to parent functions. -This means that the sequence of pseudo-random numbers that they see will -not be the same sequence of pseudo-random numbers that any parent sees. -This is only the case once \f[B]seed\f[R] has been set. -.PP -If a function desires to not affect the sequence of pseudo-random -numbers of its parents, but wants to use the same \f[B]seed\f[R], it can -use the following line: -.IP -.nf -\f[C] -seed = seed -\f[R] -.fi -.PP -If the behavior of this option is desired for every run of bc(1), then -users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this -option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more -details). -.PP -If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option -is ignored. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library and the extended math library before -running any code, including any expressions or files specified on the -command line. -.RS .PP -To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library and the extended math +library before running any code, including any expressions or files +specified on the command line. +.IP +.nf +\f[C] +To learn what is in the libraries, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Because bc(1) was built without support for prompts, this option is a +no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -308,7 +322,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -320,7 +334,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -492,7 +506,7 @@ This is a \f[B]non-portable extension\f[R]. .IP "15." 4 \f[B]irand(E)\f[R]: A pseudo-random integer between \f[B]0\f[R] (inclusive) and the value of \f[B]E\f[R] (exclusive). -If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[cq]s +If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[aq]s \f[I]scale\f[R] is not \f[B]0\f[R]), an error is raised, and bc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] remains unchanged. @@ -570,301 +584,377 @@ extension\f[R]. The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]$\f[R] -Type: Postfix -.RS .PP +: Type: Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **truncation** +\f[R] +.fi .PP -Description: \f[B]truncation\f[R] -.RE -.TP \f[B]\[at]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **set precision** +\f[R] +.fi .PP -Description: \f[B]set precision\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP \f[B]<<\f[R] \f[B]>>\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **shift left**, **shift right** +\f[R] +.fi .PP -Description: \f[B]shift left\f[R], \f[B]shift right\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP +.PP \f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]$\f[R] -The \f[B]truncation\f[R] operator returns a copy of the given expression -with all of its \f[I]scale\f[R] removed. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]truncation\f[R] operator returns a copy of the given +expression with all of its \f[I]scale\f[R] removed. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The \f[B]set precision\f[R] operator takes two expressions and returns a -copy of the first with its \f[I]scale\f[R] equal to the value of the +.PP +: The \f[B]set precision\f[R] operator takes two expressions and returns +a copy of the first with its \f[I]scale\f[R] equal to the value of the second expression. That could either mean that the number is returned without change (if the \f[I]scale\f[R] of the first expression matches the value of the second expression), extended (if it is less), or truncated (if it is more). -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]<<\f[R] -The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] and -\f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its +.PP +: The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] +and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the right. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]>>\f[R] -The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] +.PP +: The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the left. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. + +The **assignment** operators that correspond to operators that are +extensions are themselves **non-portable extensions**. +\f[R] +.fi .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP -The \f[B]assignment\f[R] operators that correspond to operators that are -extensions are themselves \f[B]non-portable extensions\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -890,7 +980,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -948,62 +1039,22 @@ Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -1099,9 +1150,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -1136,55 +1187,74 @@ are given. The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Extended Library .PP The extended library is \f[I]not\f[R] loaded when the @@ -1193,99 +1263,126 @@ options are given since they are not part of the library defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html). .PP The extended library is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p(x, y)\f[R] -Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if \f[B]y\f[R] -is not an integer, and returns the result to the current +.PP +: Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if +\f[B]y\f[R] is not an integer, and returns the result to the current \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +It is an error if **y** is negative and **x** is **0**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -It is an error if \f[B]y\f[R] is negative and \f[B]x\f[R] is -\f[B]0\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round half away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). -.TP +.PP \f[B]ceil(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero). -.TP +.PP \f[B]f(x)\f[R] -Returns the factorial of the truncated absolute value of \f[B]x\f[R]. -.TP +.PP +: Returns the factorial of the truncated absolute value of \f[B]x\f[R]. +.PP \f[B]perm(n, k)\f[R] -Returns the permutation of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the permutation of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]comb(n, k)\f[R] -Returns the combination of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the combination of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]l2(x)\f[R] -Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l10(x)\f[R] -Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]log(x, b)\f[R] -Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]cbrt(x)\f[R] -Returns the cube root of \f[B]x\f[R]. -.TP +.PP +: Returns the cube root of \f[B]x\f[R]. +.PP \f[B]root(x, n)\f[R] -Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and returns -the \f[B]r\f[R]th root of \f[B]x\f[R] to the current \f[B]scale\f[R]. -.RS .PP -If \f[B]r\f[R] is \f[B]0\f[R] or negative, this raises an error and -causes bc(1) to reset (see the \f[B]RESET\f[R] section). -It also raises an error and causes bc(1) to reset if \f[B]r\f[R] is even -and \f[B]x\f[R] is negative. -.RE -.TP +: Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and +returns the \f[B]r\f[R]th root of \f[B]x\f[R] to the current +\f[B]scale\f[R]. +.IP +.nf +\f[C] +If **r** is **0** or negative, this raises an error and causes bc(1) to +reset (see the **RESET** section). It also raises an error and causes bc(1) +to reset if **r** is even and **x** is negative. +\f[R] +.fi +.PP \f[B]pi(p)\f[R] -Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]t(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1298,60 +1395,75 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]sin(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]s(x)\f[R]. +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **s(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]cos(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]c(x)\f[R]. +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **c(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]tan(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -If \f[B]x\f[R] is equal to \f[B]1\f[R] or \f[B]-1\f[R], this raises an -error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +If **x** is equal to **1** or **-1**, this raises an error and causes bc(1) +to reset (see the **RESET** section). + +This is an alias of **t(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is an alias of \f[B]t(x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is an alias of \f[B]a(x)\f[R]. +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is an alias of **a(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1364,302 +1476,367 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is an alias of **a2(y, x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is an alias of \f[B]a2(y, x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r2d(x)\f[R] -Converts \f[B]x\f[R] from radians to degrees and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from radians to degrees and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]d2r(x)\f[R] -Converts \f[B]x\f[R] from degrees to radians and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from degrees to radians and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]frand(p)\f[R] -Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and +.PP +: Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R] (exclusive) with the number of decimal digits after the decimal point equal to the truncated absolute value of \f[B]p\f[R]. If \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]. If \f[B]p\f[R] is \f[B]0\f[R], then \f[B]0\f[R] is returned, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.TP +.PP \f[B]ifrand(i, p)\f[R] -Generates a pseudo-random number that is between \f[B]0\f[R] (inclusive) -and the truncated absolute value of \f[B]i\f[R] (exclusive) with the -number of decimal digits after the decimal point equal to the truncated -absolute value of \f[B]p\f[R]. +.PP +: Generates a pseudo-random number that is between \f[B]0\f[R] +(inclusive) and the truncated absolute value of \f[B]i\f[R] (exclusive) +with the number of decimal digits after the decimal point equal to the +truncated absolute value of \f[B]p\f[R]. If the absolute value of \f[B]i\f[R] is greater than or equal to \f[B]2\f[R], and \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]; otherwise, \f[B]0\f[R] is returned and \f[B]seed\f[R] is not changed. -.TP +.PP \f[B]srand(x)\f[R] -Returns \f[B]x\f[R] with its sign flipped with probability +.PP +: Returns \f[B]x\f[R] with its sign flipped with probability \f[B]0.5\f[R]. In other words, it randomizes the sign of \f[B]x\f[R]. -.TP +.PP \f[B]brand()\f[R] -Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). -.TP +.PP +: Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). +.PP \f[B]ubytes(x)\f[R] -Returns the numbers of unsigned integer bytes required to hold the +.PP +: Returns the numbers of unsigned integer bytes required to hold the truncated absolute value of \f[B]x\f[R]. -.TP +.PP \f[B]sbytes(x)\f[R] -Returns the numbers of signed, two\[cq]s-complement integer bytes +.PP +: Returns the numbers of signed, two\[aq]s-complement integer bytes required to hold the truncated value of \f[B]x\f[R]. -.TP +.PP \f[B]hex(x)\f[R] -Outputs the hexadecimal (base \f[B]16\f[R]) representation of +.PP +: Outputs the hexadecimal (base \f[B]16\f[R]) representation of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary(x)\f[R] -Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]output(x, b)\f[R] -Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]uint(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in as few power of two bytes as possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or is negative, an error message is printed +instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or is negative, an error message is -printed instead, but bc(1) is not reset (see the \f[B]RESET\f[R] -section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in as few power of two bytes as -possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in as few power of two bytes +as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, an error message is printed instead, but bc(1) +is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, an error message is printed instead, -but bc(1) is not reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uintn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **n** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]n\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]intn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **n** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]n\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **1** byte, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]1\f[R] byte, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **1** byte, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]1\f[R] byte, an -error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **2** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]2\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **2** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]2\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **4** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]4\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **4** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]4\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **8** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]8\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **8** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]8\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]hex_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in hexadecimal using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in binary using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in the current \f[B]obase\f[R] (see the \f[B]SYNTAX\f[R] section) using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_byte(x, i)\f[R] -Outputs byte \f[B]i\f[R] of the truncated absolute value of \f[B]x\f[R], -where \f[B]0\f[R] is the least significant byte and \f[B]number_of_bytes -- 1\f[R] is the most significant byte. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE +: Outputs byte \f[B]i\f[R] of the truncated absolute value of +\f[B]x\f[R], where \f[B]0\f[R] is the least significant byte and +\f[B]number_of_bytes - 1\f[R] is the most significant byte. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1763,64 +1940,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]rand()\f[R] +.PP +: The maximum integer (inclusive) returned by the \f[B]rand()\f[R] operand. Set at \f[B]2\[ha]BC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1832,42 +2022,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1875,68 +2067,76 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**\[rs]<\[rs]<**), and right shift (**\[rs]>\[rs]>**) +operators and their corresponding assignment operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]<<\f[R]), and right shift (\f[B]>>\f[R]) operators and their -corresponding assignment operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1966,7 +2166,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is different from interactive mode because interactive mode is required in the bc(1) @@ -1981,7 +2181,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/HP.1.md b/manuals/bc/HP.1.md index 7273a346b758..06ad718d3679 100644 --- a/manuals/bc/HP.1.md +++ b/manuals/bc/HP.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -142,6 +142,12 @@ The following are the options that bc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Because bc(1) was built without support for prompts, this option is a no-op. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/N.1 b/manuals/bc/N.1 index faf35eb8b255..d5df71cb5a18 100644 --- a/manuals/bc/N.1 +++ b/manuals/bc/N.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -58,210 +58,233 @@ implementations. .SH OPTIONS .PP The following are the options that bc(1) accepts. -.TP +.PP \f[B]-g\f[R], \f[B]--global-stacks\f[R] -Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and -\f[B]seed\f[R] into stacks. -.RS .PP -This has the effect that a copy of the current value of all four are -pushed onto a stack for every function call, as well as popped when -every function returns. -This means that functions can assign to any and all of those globals -without worrying that the change will affect other functions. -Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply -printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this: +: Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], +and \f[B]seed\f[R] into stacks. .IP .nf \f[C] -define void output(x, b) { - obase=b - x -} -\f[R] -.fi -.PP +This has the effect that a copy of the current value of all four are pushed +onto a stack for every function call, as well as popped when every function +returns. This means that functions can assign to any and all of those +globals without worrying that the change will affect other functions. +Thus, a hypothetical function named **output(x,b)** that simply printed +**x** in base **b** could be written like this: + + define void output(x, b) { + obase=b + x + } + instead of like this: -.IP -.nf -\f[C] -define void output(x, b) { - auto c - c=obase - obase=b - x - obase=c -} -\f[R] -.fi -.PP + + define void output(x, b) { + auto c + c=obase + obase=b + x + obase=c + } + This makes writing functions much easier. -.PP -(\f[B]Note\f[R]: the function \f[B]output(x,b)\f[R] exists in the -extended math library. -See the \f[B]LIBRARY\f[R] section.) -.PP -However, since using this flag means that functions cannot set -\f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] -globally, functions that are made to do so cannot work anymore. -There are two possible use cases for that, and each has a solution. -.PP + +(**Note**: the function **output(x,b)** exists in the extended math library. + See the **LIBRARY** section.) + +However, since using this flag means that functions cannot set **ibase**, +**obase**, **scale**, or **seed** globally, functions that are made to do so +cannot work anymore. There are two possible use cases for that, and each has +a solution. + First, if a function is called on startup to turn bc(1) into a number converter, it is possible to replace that capability with various shell -aliases. -Examples: -.IP -.nf -\f[C] -alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] -alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] +aliases. Examples: + + alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] + alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] + +Second, if the purpose of a function is to set **ibase**, **obase**, +**scale**, or **seed** globally for any other purpose, it could be split +into one to four functions (based on how many globals it sets) and each of +those functions could return the desired value for a global. + +For functions that set **seed**, the value assigned to **seed** is not +propagated to parent functions. This means that the sequence of +pseudo-random numbers that they see will not be the same sequence of +pseudo-random numbers that any parent sees. This is only the case once +**seed** has been set. + +If a function desires to not affect the sequence of pseudo-random numbers +of its parents, but wants to use the same **seed**, it can use the following +line: + + seed = seed + +If the behavior of this option is desired for every run of bc(1), then users +could make sure to define **BC_ENV_ARGS** and include this option (see the +**ENVIRONMENT VARIABLES** section for more details). + +If **-s**, **-w**, or any equivalents are used, this option is ignored. + +This is a **non-portable extension**. \f[R] .fi .PP -Second, if the purpose of a function is to set \f[B]ibase\f[R], -\f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] globally for any -other purpose, it could be split into one to four functions (based on -how many globals it sets) and each of those functions could return the -desired value for a global. -.PP -For functions that set \f[B]seed\f[R], the value assigned to -\f[B]seed\f[R] is not propagated to parent functions. -This means that the sequence of pseudo-random numbers that they see will -not be the same sequence of pseudo-random numbers that any parent sees. -This is only the case once \f[B]seed\f[R] has been set. -.PP -If a function desires to not affect the sequence of pseudo-random -numbers of its parents, but wants to use the same \f[B]seed\f[R], it can -use the following line: -.IP -.nf -\f[C] -seed = seed -\f[R] -.fi -.PP -If the behavior of this option is desired for every run of bc(1), then -users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this -option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more -details). -.PP -If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option -is ignored. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library and the extended math library before -running any code, including any expressions or files specified on the -command line. -.RS .PP -To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library and the extended math +library before running any code, including any expressions or files +specified on the command line. +.IP +.nf +\f[C] +To learn what is in the libraries, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in \f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in bc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of bc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **read()** built-in function is called. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -318,7 +341,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -330,7 +353,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -502,7 +525,7 @@ This is a \f[B]non-portable extension\f[R]. .IP "15." 4 \f[B]irand(E)\f[R]: A pseudo-random integer between \f[B]0\f[R] (inclusive) and the value of \f[B]E\f[R] (exclusive). -If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[cq]s +If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[aq]s \f[I]scale\f[R] is not \f[B]0\f[R]), an error is raised, and bc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] remains unchanged. @@ -580,301 +603,377 @@ extension\f[R]. The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]$\f[R] -Type: Postfix -.RS .PP +: Type: Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **truncation** +\f[R] +.fi .PP -Description: \f[B]truncation\f[R] -.RE -.TP \f[B]\[at]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **set precision** +\f[R] +.fi .PP -Description: \f[B]set precision\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP \f[B]<<\f[R] \f[B]>>\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **shift left**, **shift right** +\f[R] +.fi .PP -Description: \f[B]shift left\f[R], \f[B]shift right\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP +.PP \f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]$\f[R] -The \f[B]truncation\f[R] operator returns a copy of the given expression -with all of its \f[I]scale\f[R] removed. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]truncation\f[R] operator returns a copy of the given +expression with all of its \f[I]scale\f[R] removed. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The \f[B]set precision\f[R] operator takes two expressions and returns a -copy of the first with its \f[I]scale\f[R] equal to the value of the +.PP +: The \f[B]set precision\f[R] operator takes two expressions and returns +a copy of the first with its \f[I]scale\f[R] equal to the value of the second expression. That could either mean that the number is returned without change (if the \f[I]scale\f[R] of the first expression matches the value of the second expression), extended (if it is less), or truncated (if it is more). -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]<<\f[R] -The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] and -\f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its +.PP +: The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] +and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the right. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]>>\f[R] -The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] +.PP +: The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the left. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. + +The **assignment** operators that correspond to operators that are +extensions are themselves **non-portable extensions**. +\f[R] +.fi .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP -The \f[B]assignment\f[R] operators that correspond to operators that are -extensions are themselves \f[B]non-portable extensions\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -900,7 +999,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -958,62 +1058,22 @@ Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -1109,9 +1169,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -1146,55 +1206,74 @@ are given. The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Extended Library .PP The extended library is \f[I]not\f[R] loaded when the @@ -1203,99 +1282,126 @@ options are given since they are not part of the library defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html). .PP The extended library is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p(x, y)\f[R] -Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if \f[B]y\f[R] -is not an integer, and returns the result to the current +.PP +: Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if +\f[B]y\f[R] is not an integer, and returns the result to the current \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +It is an error if **y** is negative and **x** is **0**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -It is an error if \f[B]y\f[R] is negative and \f[B]x\f[R] is -\f[B]0\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round half away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). -.TP +.PP \f[B]ceil(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero). -.TP +.PP \f[B]f(x)\f[R] -Returns the factorial of the truncated absolute value of \f[B]x\f[R]. -.TP +.PP +: Returns the factorial of the truncated absolute value of \f[B]x\f[R]. +.PP \f[B]perm(n, k)\f[R] -Returns the permutation of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the permutation of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]comb(n, k)\f[R] -Returns the combination of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the combination of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]l2(x)\f[R] -Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l10(x)\f[R] -Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]log(x, b)\f[R] -Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]cbrt(x)\f[R] -Returns the cube root of \f[B]x\f[R]. -.TP +.PP +: Returns the cube root of \f[B]x\f[R]. +.PP \f[B]root(x, n)\f[R] -Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and returns -the \f[B]r\f[R]th root of \f[B]x\f[R] to the current \f[B]scale\f[R]. -.RS .PP -If \f[B]r\f[R] is \f[B]0\f[R] or negative, this raises an error and -causes bc(1) to reset (see the \f[B]RESET\f[R] section). -It also raises an error and causes bc(1) to reset if \f[B]r\f[R] is even -and \f[B]x\f[R] is negative. -.RE -.TP +: Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and +returns the \f[B]r\f[R]th root of \f[B]x\f[R] to the current +\f[B]scale\f[R]. +.IP +.nf +\f[C] +If **r** is **0** or negative, this raises an error and causes bc(1) to +reset (see the **RESET** section). It also raises an error and causes bc(1) +to reset if **r** is even and **x** is negative. +\f[R] +.fi +.PP \f[B]pi(p)\f[R] -Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]t(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1308,60 +1414,75 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]sin(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]s(x)\f[R]. +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **s(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]cos(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]c(x)\f[R]. +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **c(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]tan(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -If \f[B]x\f[R] is equal to \f[B]1\f[R] or \f[B]-1\f[R], this raises an -error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +If **x** is equal to **1** or **-1**, this raises an error and causes bc(1) +to reset (see the **RESET** section). + +This is an alias of **t(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is an alias of \f[B]t(x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is an alias of \f[B]a(x)\f[R]. +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is an alias of **a(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1374,302 +1495,367 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is an alias of **a2(y, x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is an alias of \f[B]a2(y, x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r2d(x)\f[R] -Converts \f[B]x\f[R] from radians to degrees and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from radians to degrees and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]d2r(x)\f[R] -Converts \f[B]x\f[R] from degrees to radians and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from degrees to radians and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]frand(p)\f[R] -Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and +.PP +: Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R] (exclusive) with the number of decimal digits after the decimal point equal to the truncated absolute value of \f[B]p\f[R]. If \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]. If \f[B]p\f[R] is \f[B]0\f[R], then \f[B]0\f[R] is returned, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.TP +.PP \f[B]ifrand(i, p)\f[R] -Generates a pseudo-random number that is between \f[B]0\f[R] (inclusive) -and the truncated absolute value of \f[B]i\f[R] (exclusive) with the -number of decimal digits after the decimal point equal to the truncated -absolute value of \f[B]p\f[R]. +.PP +: Generates a pseudo-random number that is between \f[B]0\f[R] +(inclusive) and the truncated absolute value of \f[B]i\f[R] (exclusive) +with the number of decimal digits after the decimal point equal to the +truncated absolute value of \f[B]p\f[R]. If the absolute value of \f[B]i\f[R] is greater than or equal to \f[B]2\f[R], and \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]; otherwise, \f[B]0\f[R] is returned and \f[B]seed\f[R] is not changed. -.TP +.PP \f[B]srand(x)\f[R] -Returns \f[B]x\f[R] with its sign flipped with probability +.PP +: Returns \f[B]x\f[R] with its sign flipped with probability \f[B]0.5\f[R]. In other words, it randomizes the sign of \f[B]x\f[R]. -.TP +.PP \f[B]brand()\f[R] -Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). -.TP +.PP +: Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). +.PP \f[B]ubytes(x)\f[R] -Returns the numbers of unsigned integer bytes required to hold the +.PP +: Returns the numbers of unsigned integer bytes required to hold the truncated absolute value of \f[B]x\f[R]. -.TP +.PP \f[B]sbytes(x)\f[R] -Returns the numbers of signed, two\[cq]s-complement integer bytes +.PP +: Returns the numbers of signed, two\[aq]s-complement integer bytes required to hold the truncated value of \f[B]x\f[R]. -.TP +.PP \f[B]hex(x)\f[R] -Outputs the hexadecimal (base \f[B]16\f[R]) representation of +.PP +: Outputs the hexadecimal (base \f[B]16\f[R]) representation of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary(x)\f[R] -Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]output(x, b)\f[R] -Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]uint(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in as few power of two bytes as possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or is negative, an error message is printed +instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or is negative, an error message is -printed instead, but bc(1) is not reset (see the \f[B]RESET\f[R] -section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in as few power of two bytes as -possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in as few power of two bytes +as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, an error message is printed instead, but bc(1) +is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, an error message is printed instead, -but bc(1) is not reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uintn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **n** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]n\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]intn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **n** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]n\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **1** byte, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]1\f[R] byte, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **1** byte, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]1\f[R] byte, an -error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **2** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]2\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **2** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]2\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **4** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]4\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **4** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]4\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **8** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]8\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **8** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]8\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]hex_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in hexadecimal using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in binary using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in the current \f[B]obase\f[R] (see the \f[B]SYNTAX\f[R] section) using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_byte(x, i)\f[R] -Outputs byte \f[B]i\f[R] of the truncated absolute value of \f[B]x\f[R], -where \f[B]0\f[R] is the least significant byte and \f[B]number_of_bytes -- 1\f[R] is the most significant byte. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE +: Outputs byte \f[B]i\f[R] of the truncated absolute value of +\f[B]x\f[R], where \f[B]0\f[R] is the least significant byte and +\f[B]number_of_bytes - 1\f[R] is the most significant byte. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1773,64 +1959,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]rand()\f[R] +.PP +: The maximum integer (inclusive) returned by the \f[B]rand()\f[R] operand. Set at \f[B]2\[ha]BC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1842,42 +2041,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1885,68 +2086,76 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**\[rs]<\[rs]<**), and right shift (**\[rs]>\[rs]>**) +operators and their corresponding assignment operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]<<\f[R]), and right shift (\f[B]>>\f[R]) operators and their -corresponding assignment operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1976,7 +2185,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1998,7 +2207,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/N.1.md b/manuals/bc/N.1.md index 5c877ef79823..1bb215640871 100644 --- a/manuals/bc/N.1.md +++ b/manuals/bc/N.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -143,13 +143,27 @@ The following are the options that bc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in bc(1). Most of those users would want to put this option in **BC_ENV_ARGS** (see the **ENVIRONMENT VARIABLES** section). This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in bc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of bc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **read()** built-in function is called. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/NP.1 b/manuals/bc/NP.1 index 149037fd9705..339ab9e214d9 100644 --- a/manuals/bc/NP.1 +++ b/manuals/bc/NP.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -58,205 +58,219 @@ implementations. .SH OPTIONS .PP The following are the options that bc(1) accepts. -.TP +.PP \f[B]-g\f[R], \f[B]--global-stacks\f[R] -Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and -\f[B]seed\f[R] into stacks. -.RS .PP -This has the effect that a copy of the current value of all four are -pushed onto a stack for every function call, as well as popped when -every function returns. -This means that functions can assign to any and all of those globals -without worrying that the change will affect other functions. -Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply -printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this: +: Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], +and \f[B]seed\f[R] into stacks. .IP .nf \f[C] -define void output(x, b) { - obase=b - x -} -\f[R] -.fi -.PP +This has the effect that a copy of the current value of all four are pushed +onto a stack for every function call, as well as popped when every function +returns. This means that functions can assign to any and all of those +globals without worrying that the change will affect other functions. +Thus, a hypothetical function named **output(x,b)** that simply printed +**x** in base **b** could be written like this: + + define void output(x, b) { + obase=b + x + } + instead of like this: -.IP -.nf -\f[C] -define void output(x, b) { - auto c - c=obase - obase=b - x - obase=c -} -\f[R] -.fi -.PP + + define void output(x, b) { + auto c + c=obase + obase=b + x + obase=c + } + This makes writing functions much easier. -.PP -(\f[B]Note\f[R]: the function \f[B]output(x,b)\f[R] exists in the -extended math library. -See the \f[B]LIBRARY\f[R] section.) -.PP -However, since using this flag means that functions cannot set -\f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] -globally, functions that are made to do so cannot work anymore. -There are two possible use cases for that, and each has a solution. -.PP + +(**Note**: the function **output(x,b)** exists in the extended math library. + See the **LIBRARY** section.) + +However, since using this flag means that functions cannot set **ibase**, +**obase**, **scale**, or **seed** globally, functions that are made to do so +cannot work anymore. There are two possible use cases for that, and each has +a solution. + First, if a function is called on startup to turn bc(1) into a number converter, it is possible to replace that capability with various shell -aliases. -Examples: -.IP -.nf -\f[C] -alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] -alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] +aliases. Examples: + + alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] + alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] + +Second, if the purpose of a function is to set **ibase**, **obase**, +**scale**, or **seed** globally for any other purpose, it could be split +into one to four functions (based on how many globals it sets) and each of +those functions could return the desired value for a global. + +For functions that set **seed**, the value assigned to **seed** is not +propagated to parent functions. This means that the sequence of +pseudo-random numbers that they see will not be the same sequence of +pseudo-random numbers that any parent sees. This is only the case once +**seed** has been set. + +If a function desires to not affect the sequence of pseudo-random numbers +of its parents, but wants to use the same **seed**, it can use the following +line: + + seed = seed + +If the behavior of this option is desired for every run of bc(1), then users +could make sure to define **BC_ENV_ARGS** and include this option (see the +**ENVIRONMENT VARIABLES** section for more details). + +If **-s**, **-w**, or any equivalents are used, this option is ignored. + +This is a **non-portable extension**. \f[R] .fi .PP -Second, if the purpose of a function is to set \f[B]ibase\f[R], -\f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] globally for any -other purpose, it could be split into one to four functions (based on -how many globals it sets) and each of those functions could return the -desired value for a global. -.PP -For functions that set \f[B]seed\f[R], the value assigned to -\f[B]seed\f[R] is not propagated to parent functions. -This means that the sequence of pseudo-random numbers that they see will -not be the same sequence of pseudo-random numbers that any parent sees. -This is only the case once \f[B]seed\f[R] has been set. -.PP -If a function desires to not affect the sequence of pseudo-random -numbers of its parents, but wants to use the same \f[B]seed\f[R], it can -use the following line: -.IP -.nf -\f[C] -seed = seed -\f[R] -.fi -.PP -If the behavior of this option is desired for every run of bc(1), then -users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this -option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more -details). -.PP -If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option -is ignored. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library and the extended math library before -running any code, including any expressions or files specified on the -command line. -.RS .PP -To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library and the extended math +library before running any code, including any expressions or files +specified on the command line. +.IP +.nf +\f[C] +To learn what is in the libraries, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Because bc(1) was built without support for prompts, this option is a +no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -313,7 +327,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -325,7 +339,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -497,7 +511,7 @@ This is a \f[B]non-portable extension\f[R]. .IP "15." 4 \f[B]irand(E)\f[R]: A pseudo-random integer between \f[B]0\f[R] (inclusive) and the value of \f[B]E\f[R] (exclusive). -If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[cq]s +If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[aq]s \f[I]scale\f[R] is not \f[B]0\f[R]), an error is raised, and bc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] remains unchanged. @@ -575,301 +589,377 @@ extension\f[R]. The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]$\f[R] -Type: Postfix -.RS .PP +: Type: Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **truncation** +\f[R] +.fi .PP -Description: \f[B]truncation\f[R] -.RE -.TP \f[B]\[at]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **set precision** +\f[R] +.fi .PP -Description: \f[B]set precision\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP \f[B]<<\f[R] \f[B]>>\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **shift left**, **shift right** +\f[R] +.fi .PP -Description: \f[B]shift left\f[R], \f[B]shift right\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP +.PP \f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]$\f[R] -The \f[B]truncation\f[R] operator returns a copy of the given expression -with all of its \f[I]scale\f[R] removed. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]truncation\f[R] operator returns a copy of the given +expression with all of its \f[I]scale\f[R] removed. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The \f[B]set precision\f[R] operator takes two expressions and returns a -copy of the first with its \f[I]scale\f[R] equal to the value of the +.PP +: The \f[B]set precision\f[R] operator takes two expressions and returns +a copy of the first with its \f[I]scale\f[R] equal to the value of the second expression. That could either mean that the number is returned without change (if the \f[I]scale\f[R] of the first expression matches the value of the second expression), extended (if it is less), or truncated (if it is more). -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]<<\f[R] -The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] and -\f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its +.PP +: The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] +and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the right. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]>>\f[R] -The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] +.PP +: The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the left. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. + +The **assignment** operators that correspond to operators that are +extensions are themselves **non-portable extensions**. +\f[R] +.fi .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP -The \f[B]assignment\f[R] operators that correspond to operators that are -extensions are themselves \f[B]non-portable extensions\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -895,7 +985,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -953,62 +1044,22 @@ Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -1104,9 +1155,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -1141,55 +1192,74 @@ are given. The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Extended Library .PP The extended library is \f[I]not\f[R] loaded when the @@ -1198,99 +1268,126 @@ options are given since they are not part of the library defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html). .PP The extended library is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p(x, y)\f[R] -Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if \f[B]y\f[R] -is not an integer, and returns the result to the current +.PP +: Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if +\f[B]y\f[R] is not an integer, and returns the result to the current \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +It is an error if **y** is negative and **x** is **0**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -It is an error if \f[B]y\f[R] is negative and \f[B]x\f[R] is -\f[B]0\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round half away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). -.TP +.PP \f[B]ceil(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero). -.TP +.PP \f[B]f(x)\f[R] -Returns the factorial of the truncated absolute value of \f[B]x\f[R]. -.TP +.PP +: Returns the factorial of the truncated absolute value of \f[B]x\f[R]. +.PP \f[B]perm(n, k)\f[R] -Returns the permutation of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the permutation of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]comb(n, k)\f[R] -Returns the combination of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the combination of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]l2(x)\f[R] -Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l10(x)\f[R] -Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]log(x, b)\f[R] -Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]cbrt(x)\f[R] -Returns the cube root of \f[B]x\f[R]. -.TP +.PP +: Returns the cube root of \f[B]x\f[R]. +.PP \f[B]root(x, n)\f[R] -Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and returns -the \f[B]r\f[R]th root of \f[B]x\f[R] to the current \f[B]scale\f[R]. -.RS .PP -If \f[B]r\f[R] is \f[B]0\f[R] or negative, this raises an error and -causes bc(1) to reset (see the \f[B]RESET\f[R] section). -It also raises an error and causes bc(1) to reset if \f[B]r\f[R] is even -and \f[B]x\f[R] is negative. -.RE -.TP +: Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and +returns the \f[B]r\f[R]th root of \f[B]x\f[R] to the current +\f[B]scale\f[R]. +.IP +.nf +\f[C] +If **r** is **0** or negative, this raises an error and causes bc(1) to +reset (see the **RESET** section). It also raises an error and causes bc(1) +to reset if **r** is even and **x** is negative. +\f[R] +.fi +.PP \f[B]pi(p)\f[R] -Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]t(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1303,60 +1400,75 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]sin(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]s(x)\f[R]. +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **s(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]cos(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]c(x)\f[R]. +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **c(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]tan(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -If \f[B]x\f[R] is equal to \f[B]1\f[R] or \f[B]-1\f[R], this raises an -error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +If **x** is equal to **1** or **-1**, this raises an error and causes bc(1) +to reset (see the **RESET** section). + +This is an alias of **t(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is an alias of \f[B]t(x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is an alias of \f[B]a(x)\f[R]. +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is an alias of **a(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1369,302 +1481,367 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is an alias of **a2(y, x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is an alias of \f[B]a2(y, x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r2d(x)\f[R] -Converts \f[B]x\f[R] from radians to degrees and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from radians to degrees and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]d2r(x)\f[R] -Converts \f[B]x\f[R] from degrees to radians and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from degrees to radians and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]frand(p)\f[R] -Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and +.PP +: Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R] (exclusive) with the number of decimal digits after the decimal point equal to the truncated absolute value of \f[B]p\f[R]. If \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]. If \f[B]p\f[R] is \f[B]0\f[R], then \f[B]0\f[R] is returned, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.TP +.PP \f[B]ifrand(i, p)\f[R] -Generates a pseudo-random number that is between \f[B]0\f[R] (inclusive) -and the truncated absolute value of \f[B]i\f[R] (exclusive) with the -number of decimal digits after the decimal point equal to the truncated -absolute value of \f[B]p\f[R]. +.PP +: Generates a pseudo-random number that is between \f[B]0\f[R] +(inclusive) and the truncated absolute value of \f[B]i\f[R] (exclusive) +with the number of decimal digits after the decimal point equal to the +truncated absolute value of \f[B]p\f[R]. If the absolute value of \f[B]i\f[R] is greater than or equal to \f[B]2\f[R], and \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]; otherwise, \f[B]0\f[R] is returned and \f[B]seed\f[R] is not changed. -.TP +.PP \f[B]srand(x)\f[R] -Returns \f[B]x\f[R] with its sign flipped with probability +.PP +: Returns \f[B]x\f[R] with its sign flipped with probability \f[B]0.5\f[R]. In other words, it randomizes the sign of \f[B]x\f[R]. -.TP +.PP \f[B]brand()\f[R] -Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). -.TP +.PP +: Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). +.PP \f[B]ubytes(x)\f[R] -Returns the numbers of unsigned integer bytes required to hold the +.PP +: Returns the numbers of unsigned integer bytes required to hold the truncated absolute value of \f[B]x\f[R]. -.TP +.PP \f[B]sbytes(x)\f[R] -Returns the numbers of signed, two\[cq]s-complement integer bytes +.PP +: Returns the numbers of signed, two\[aq]s-complement integer bytes required to hold the truncated value of \f[B]x\f[R]. -.TP +.PP \f[B]hex(x)\f[R] -Outputs the hexadecimal (base \f[B]16\f[R]) representation of +.PP +: Outputs the hexadecimal (base \f[B]16\f[R]) representation of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary(x)\f[R] -Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]output(x, b)\f[R] -Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]uint(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in as few power of two bytes as possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or is negative, an error message is printed +instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or is negative, an error message is -printed instead, but bc(1) is not reset (see the \f[B]RESET\f[R] -section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in as few power of two bytes as -possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in as few power of two bytes +as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, an error message is printed instead, but bc(1) +is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, an error message is printed instead, -but bc(1) is not reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uintn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **n** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]n\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]intn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **n** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]n\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **1** byte, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]1\f[R] byte, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **1** byte, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]1\f[R] byte, an -error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **2** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]2\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **2** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]2\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **4** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]4\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **4** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]4\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **8** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]8\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **8** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]8\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]hex_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in hexadecimal using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in binary using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in the current \f[B]obase\f[R] (see the \f[B]SYNTAX\f[R] section) using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_byte(x, i)\f[R] -Outputs byte \f[B]i\f[R] of the truncated absolute value of \f[B]x\f[R], -where \f[B]0\f[R] is the least significant byte and \f[B]number_of_bytes -- 1\f[R] is the most significant byte. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE +: Outputs byte \f[B]i\f[R] of the truncated absolute value of +\f[B]x\f[R], where \f[B]0\f[R] is the least significant byte and +\f[B]number_of_bytes - 1\f[R] is the most significant byte. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1768,64 +1945,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]rand()\f[R] +.PP +: The maximum integer (inclusive) returned by the \f[B]rand()\f[R] operand. Set at \f[B]2\[ha]BC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1837,42 +2027,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1880,68 +2072,76 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**\[rs]<\[rs]<**), and right shift (**\[rs]>\[rs]>**) +operators and their corresponding assignment operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]<<\f[R]), and right shift (\f[B]>>\f[R]) operators and their -corresponding assignment operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1971,7 +2171,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1991,7 +2191,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/NP.1.md b/manuals/bc/NP.1.md index 518d237020df..c8ae18b194bf 100644 --- a/manuals/bc/NP.1.md +++ b/manuals/bc/NP.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -146,6 +146,12 @@ The following are the options that bc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Because bc(1) was built without support for prompts, this option is a no-op. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bc/P.1 b/manuals/bc/P.1 index cfe4afe1fdf3..ed539824b385 100644 --- a/manuals/bc/P.1 +++ b/manuals/bc/P.1 @@ -25,19 +25,19 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH NAME .PP bc - arbitrary-precision decimal arithmetic language and calculator .SH SYNOPSIS .PP -\f[B]bc\f[R] [\f[B]-ghilPqsvVw\f[R]] [\f[B]--global-stacks\f[R]] +\f[B]bc\f[R] [\f[B]-ghilPqRsvVw\f[R]] [\f[B]--global-stacks\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--mathlib\f[R]] -[\f[B]--no-prompt\f[R]] [\f[B]--quiet\f[R]] [\f[B]--standard\f[R]] -[\f[B]--warn\f[R]] [\f[B]--version\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-prompt\f[R]] [\f[B]--no-read-prompt\f[R]] [\f[B]--quiet\f[R]] +[\f[B]--standard\f[R]] [\f[B]--warn\f[R]] [\f[B]--version\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP bc(1) is an interactive processor for a language first standardized in @@ -58,205 +58,219 @@ implementations. .SH OPTIONS .PP The following are the options that bc(1) accepts. -.TP +.PP \f[B]-g\f[R], \f[B]--global-stacks\f[R] -Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and -\f[B]seed\f[R] into stacks. -.RS .PP -This has the effect that a copy of the current value of all four are -pushed onto a stack for every function call, as well as popped when -every function returns. -This means that functions can assign to any and all of those globals -without worrying that the change will affect other functions. -Thus, a hypothetical function named \f[B]output(x,b)\f[R] that simply -printed \f[B]x\f[R] in base \f[B]b\f[R] could be written like this: +: Turns the globals \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], +and \f[B]seed\f[R] into stacks. .IP .nf \f[C] -define void output(x, b) { - obase=b - x -} -\f[R] -.fi -.PP +This has the effect that a copy of the current value of all four are pushed +onto a stack for every function call, as well as popped when every function +returns. This means that functions can assign to any and all of those +globals without worrying that the change will affect other functions. +Thus, a hypothetical function named **output(x,b)** that simply printed +**x** in base **b** could be written like this: + + define void output(x, b) { + obase=b + x + } + instead of like this: -.IP -.nf -\f[C] -define void output(x, b) { - auto c - c=obase - obase=b - x - obase=c -} -\f[R] -.fi -.PP + + define void output(x, b) { + auto c + c=obase + obase=b + x + obase=c + } + This makes writing functions much easier. -.PP -(\f[B]Note\f[R]: the function \f[B]output(x,b)\f[R] exists in the -extended math library. -See the \f[B]LIBRARY\f[R] section.) -.PP -However, since using this flag means that functions cannot set -\f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] -globally, functions that are made to do so cannot work anymore. -There are two possible use cases for that, and each has a solution. -.PP + +(**Note**: the function **output(x,b)** exists in the extended math library. + See the **LIBRARY** section.) + +However, since using this flag means that functions cannot set **ibase**, +**obase**, **scale**, or **seed** globally, functions that are made to do so +cannot work anymore. There are two possible use cases for that, and each has +a solution. + First, if a function is called on startup to turn bc(1) into a number converter, it is possible to replace that capability with various shell -aliases. -Examples: -.IP -.nf -\f[C] -alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] -alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] +aliases. Examples: + + alias d2o=\[dq]bc -e ibase=A -e obase=8\[dq] + alias h2b=\[dq]bc -e ibase=G -e obase=2\[dq] + +Second, if the purpose of a function is to set **ibase**, **obase**, +**scale**, or **seed** globally for any other purpose, it could be split +into one to four functions (based on how many globals it sets) and each of +those functions could return the desired value for a global. + +For functions that set **seed**, the value assigned to **seed** is not +propagated to parent functions. This means that the sequence of +pseudo-random numbers that they see will not be the same sequence of +pseudo-random numbers that any parent sees. This is only the case once +**seed** has been set. + +If a function desires to not affect the sequence of pseudo-random numbers +of its parents, but wants to use the same **seed**, it can use the following +line: + + seed = seed + +If the behavior of this option is desired for every run of bc(1), then users +could make sure to define **BC_ENV_ARGS** and include this option (see the +**ENVIRONMENT VARIABLES** section for more details). + +If **-s**, **-w**, or any equivalents are used, this option is ignored. + +This is a **non-portable extension**. \f[R] .fi .PP -Second, if the purpose of a function is to set \f[B]ibase\f[R], -\f[B]obase\f[R], \f[B]scale\f[R], or \f[B]seed\f[R] globally for any -other purpose, it could be split into one to four functions (based on -how many globals it sets) and each of those functions could return the -desired value for a global. -.PP -For functions that set \f[B]seed\f[R], the value assigned to -\f[B]seed\f[R] is not propagated to parent functions. -This means that the sequence of pseudo-random numbers that they see will -not be the same sequence of pseudo-random numbers that any parent sees. -This is only the case once \f[B]seed\f[R] has been set. -.PP -If a function desires to not affect the sequence of pseudo-random -numbers of its parents, but wants to use the same \f[B]seed\f[R], it can -use the following line: -.IP -.nf -\f[C] -seed = seed -\f[R] -.fi -.PP -If the behavior of this option is desired for every run of bc(1), then -users could make sure to define \f[B]BC_ENV_ARGS\f[R] and include this -option (see the \f[B]ENVIRONMENT VARIABLES\f[R] section for more -details). -.PP -If \f[B]-s\f[R], \f[B]-w\f[R], or any equivalents are used, this option -is ignored. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-l\f[R], \f[B]--mathlib\f[R] -Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to \f[B]20\f[R] -and loads the included math library and the extended math library before -running any code, including any expressions or files specified on the -command line. -.RS .PP -To learn what is in the libraries, see the \f[B]LIBRARY\f[R] section. -.RE -.TP +: Sets \f[B]scale\f[R] (see the \f[B]SYNTAX\f[R] section) to +\f[B]20\f[R] and loads the included math library and the extended math +library before running any code, including any expressions or files +specified on the command line. +.IP +.nf +\f[C] +To learn what is in the libraries, see the **LIBRARY** section. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Because bc(1) was built without support for prompts, this option is a +no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-q\f[R], \f[B]--quiet\f[R] -This option is for compatibility with the GNU +.PP +: This option is for compatibility with the GNU bc(1) (https://www.gnu.org/software/bc/); it is a no-op. Without this option, GNU bc(1) prints a copyright header. This bc(1) only prints the copyright header if one or more of the \f[B]-v\f[R], \f[B]-V\f[R], or \f[B]--version\f[R] options are given. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-s\f[R], \f[B]--standard\f[R] -Process exactly the language defined by the +.PP +: Process exactly the language defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) and error if any extensions are used. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Print the version information (copyright header) and exit. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-w\f[R], \f[B]--warn\f[R] -Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and +.PP +: Like \f[B]-s\f[R] and \f[B]--standard\f[R], except that warnings (and not errors) are printed for non-standard extensions and execution continues normally. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **BC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]BC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]BC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, bc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, bc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **BC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, bc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, bc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -313,7 +327,7 @@ Identifiers with more than one character (letter) are a .PP \f[B]ibase\f[R] is a global variable determining how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. If the \f[B]-s\f[R] (\f[B]--standard\f[R]) and \f[B]-w\f[R] @@ -325,7 +339,7 @@ The max allowable value for \f[B]ibase\f[R] can be queried in bc(1) programs with the \f[B]maxibase()\f[R] built-in function. .PP \f[B]obase\f[R] is a global variable determining how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]BC_BASE_MAX\f[R] and @@ -497,7 +511,7 @@ This is a \f[B]non-portable extension\f[R]. .IP "15." 4 \f[B]irand(E)\f[R]: A pseudo-random integer between \f[B]0\f[R] (inclusive) and the value of \f[B]E\f[R] (exclusive). -If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[cq]s +If \f[B]E\f[R] is negative or is a non-integer (\f[B]E\f[R]\[aq]s \f[I]scale\f[R] is not \f[B]0\f[R]), an error is raised, and bc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] remains unchanged. @@ -575,301 +589,377 @@ extension\f[R]. The following arithmetic and logical operators can be used. They are listed in order of decreasing precedence. Operators in the same group have the same precedence. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -Type: Prefix and Postfix -.RS .PP +: Type: Prefix and Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **increment**, **decrement** +\f[R] +.fi .PP -Description: \f[B]increment\f[R], \f[B]decrement\f[R] -.RE -.TP \f[B]-\f[R] \f[B]!\f[R] -Type: Prefix -.RS .PP +: Type: Prefix +.IP +.nf +\f[C] Associativity: None + +Description: **negation**, **boolean not** +\f[R] +.fi .PP -Description: \f[B]negation\f[R], \f[B]boolean not\f[R] -.RE -.TP \f[B]$\f[R] -Type: Postfix -.RS .PP +: Type: Postfix +.IP +.nf +\f[C] Associativity: None + +Description: **truncation** +\f[R] +.fi .PP -Description: \f[B]truncation\f[R] -.RE -.TP \f[B]\[at]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **set precision** +\f[R] +.fi .PP -Description: \f[B]set precision\f[R] -.RE -.TP \f[B]\[ha]\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **power** +\f[R] +.fi .PP -Description: \f[B]power\f[R] -.RE -.TP \f[B]*\f[R] \f[B]/\f[R] \f[B]%\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **multiply**, **divide**, **modulus** +\f[R] +.fi .PP -Description: \f[B]multiply\f[R], \f[B]divide\f[R], \f[B]modulus\f[R] -.RE -.TP \f[B]+\f[R] \f[B]-\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **add**, **subtract** +\f[R] +.fi .PP -Description: \f[B]add\f[R], \f[B]subtract\f[R] -.RE -.TP \f[B]<<\f[R] \f[B]>>\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **shift left**, **shift right** +\f[R] +.fi .PP -Description: \f[B]shift left\f[R], \f[B]shift right\f[R] -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -Type: Binary -.RS +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Right + +Description: **assignment** +\f[R] +.fi .PP -Description: \f[B]assignment\f[R] -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -Type: Binary -.RS +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **relational** +\f[R] +.fi .PP -Description: \f[B]relational\f[R] -.RE -.TP \f[B]&&\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left + +Description: **boolean and** +\f[R] +.fi .PP -Description: \f[B]boolean and\f[R] -.RE -.TP \f[B]||\f[R] -Type: Binary -.RS .PP +: Type: Binary +.IP +.nf +\f[C] Associativity: Left -.PP -Description: \f[B]boolean or\f[R] -.RE + +Description: **boolean or** +\f[R] +.fi .PP The operators will be described in more detail below. -.TP +.PP \f[B]++\f[R] \f[B]--\f[R] -The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] +.PP +: The prefix and postfix \f[B]increment\f[R] and \f[B]decrement\f[R] operators behave exactly like they would in C. They require a named expression (see the \f[I]Named Expressions\f[R] subsection) as an operand. -.RS +.IP +.nf +\f[C] +The prefix versions of these operators are more efficient; use them where +possible. +\f[R] +.fi .PP -The prefix versions of these operators are more efficient; use them -where possible. -.RE -.TP \f[B]-\f[R] -The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts +.PP +: The \f[B]negation\f[R] operator returns \f[B]0\f[R] if a user attempts to negate any expression with the value \f[B]0\f[R]. Otherwise, a copy of the expression with its sign flipped is returned. -.TP +.PP \f[B]!\f[R] -The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the expression -is \f[B]0\f[R], or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]boolean not\f[R] operator returns \f[B]1\f[R] if the +expression is \f[B]0\f[R], or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]$\f[R] -The \f[B]truncation\f[R] operator returns a copy of the given expression -with all of its \f[I]scale\f[R] removed. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The \f[B]truncation\f[R] operator returns a copy of the given +expression with all of its \f[I]scale\f[R] removed. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The \f[B]set precision\f[R] operator takes two expressions and returns a -copy of the first with its \f[I]scale\f[R] equal to the value of the +.PP +: The \f[B]set precision\f[R] operator takes two expressions and returns +a copy of the first with its \f[I]scale\f[R] equal to the value of the second expression. That could either mean that the number is returned without change (if the \f[I]scale\f[R] of the first expression matches the value of the second expression), extended (if it is less), or truncated (if it is more). -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, +.PP +: The \f[B]power\f[R] operator (not the \f[B]exclusive or\f[R] operator, as it would be in C) takes two expressions and raises the first to the power of the value of the second. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*), and if it is +negative, the first value must be non-zero. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]), and if it -is negative, the first value must be non-zero. -.RE -.TP \f[B]*\f[R] -The \f[B]multiply\f[R] operator takes two expressions, multiplies them, -and returns the product. +.PP +: The \f[B]multiply\f[R] operator takes two expressions, multiplies +them, and returns the product. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The \f[B]divide\f[R] operator takes two expressions, divides them, and +.PP +: The \f[B]divide\f[R] operator takes two expressions, divides them, and returns the quotient. The \f[I]scale\f[R] of the result shall be the value of \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]%\f[R] -The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]modulus\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and evaluates them by 1) Computing \f[B]a/b\f[R] to current \f[B]scale\f[R] and 2) Using the result of step 1 to calculate \f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] \f[B]max(scale+scale(b),scale(a))\f[R]. -.RS -.PP +.IP +.nf +\f[C] The second expression must be non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]+\f[R] -The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]add\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the sum, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]-\f[R] -The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and +.PP +: The \f[B]subtract\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns the difference, with a \f[I]scale\f[R] equal to the max of the \f[I]scale\f[R]s of \f[B]a\f[R] and \f[B]b\f[R]. -.TP +.PP \f[B]<<\f[R] -The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] and -\f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its +.PP +: The \f[B]left shift\f[R] operator takes two expressions, \f[B]a\f[R] +and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the right. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]>>\f[R] -The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] +.PP +: The \f[B]right shift\f[R] operator takes two expressions, \f[B]a\f[R] and \f[B]b\f[R], and returns a copy of the value of \f[B]a\f[R] with its decimal point moved \f[B]b\f[R] places to the left. -.RS +.IP +.nf +\f[C] +The second expression must be an integer (no *scale*) and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The second expression must be an integer (no \f[I]scale\f[R]) and -non-negative. +\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] +\f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]=\f[R] \f[B]<<=\f[R] \f[B]>>=\f[R] \f[B]+=\f[R] \f[B]-=\f[R] \f[B]*=\f[R] \f[B]/=\f[R] \f[B]%=\f[R] \f[B]\[ha]=\f[R] \f[B]\[at]=\f[R] -The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] and -\f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the \f[I]Named -Expressions\f[R] subsection). -.RS +: The \f[B]assignment\f[R] operators take two expressions, \f[B]a\f[R] +and \f[B]b\f[R] where \f[B]a\f[R] is a named expression (see the +\f[I]Named Expressions\f[R] subsection). +.IP +.nf +\f[C] +For **=**, **b** is copied and the result is assigned to **a**. For all +others, **a** and **b** are applied as operands to the corresponding +arithmetic operator and the result is assigned to **a**. + +The **assignment** operators that correspond to operators that are +extensions are themselves **non-portable extensions**. +\f[R] +.fi .PP -For \f[B]=\f[R], \f[B]b\f[R] is copied and the result is assigned to -\f[B]a\f[R]. -For all others, \f[B]a\f[R] and \f[B]b\f[R] are applied as operands to -the corresponding arithmetic operator and the result is assigned to -\f[B]a\f[R]. +\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] +\f[B]>\f[R] .PP -The \f[B]assignment\f[R] operators that correspond to operators that are -extensions are themselves \f[B]non-portable extensions\f[R]. -.RE -.TP -\f[B]==\f[R] \f[B]<=\f[R] \f[B]>=\f[R] \f[B]!=\f[R] \f[B]<\f[R] \f[B]>\f[R] -The \f[B]relational\f[R] operators compare two expressions, \f[B]a\f[R] -and \f[B]b\f[R], and if the relation holds, according to C language -semantics, the result is \f[B]1\f[R]. +: The \f[B]relational\f[R] operators compare two expressions, +\f[B]a\f[R] and \f[B]b\f[R], and if the relation holds, according to C +language semantics, the result is \f[B]1\f[R]. Otherwise, it is \f[B]0\f[R]. -.RS -.PP +.IP +.nf +\f[C] Note that unlike in C, these operators have a lower precedence than the -\f[B]assignment\f[R] operators, which means that \f[B]a=b>c\f[R] is -interpreted as \f[B](a=b)>c\f[R]. +**assignment** operators, which means that **a=b\[rs]>c** is interpreted as +**(a=b)\[rs]>c**. + +Also, unlike the [standard][1] requires, these operators can appear anywhere +any other expressions can be used. This allowance is a +**non-portable extension**. +\f[R] +.fi .PP -Also, unlike the -standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) -requires, these operators can appear anywhere any other expressions can -be used. -This allowance is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]&&\f[R] -The \f[B]boolean and\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean and\f[R] operator takes two expressions and returns \f[B]1\f[R] if both expressions are non-zero, \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]||\f[R] -The \f[B]boolean or\f[R] operator takes two expressions and returns +.PP +: The \f[B]boolean or\f[R] operator takes two expressions and returns \f[B]1\f[R] if one of the expressions is non-zero, \f[B]0\f[R] otherwise. -.RS -.PP -This is \f[I]not\f[R] a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is *not* a short-circuit operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Statements .PP The following items are statements: .IP " 1." 4 \f[B]E\f[R] .IP " 2." 4 -\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] \&... \f[B];\f[R] \f[B]S\f[R] -\f[B]}\f[R] +\f[B]{\f[R] \f[B]S\f[R] \f[B];\f[R] ... +\f[B];\f[R] \f[B]S\f[R] \f[B]}\f[R] .IP " 3." 4 \f[B]if\f[R] \f[B](\f[R] \f[B]E\f[R] \f[B])\f[R] \f[B]S\f[R] .IP " 4." 4 @@ -895,7 +985,8 @@ An empty statement .IP "13." 4 A string of characters, enclosed in double quotes .IP "14." 4 -\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] \&... \f[B],\f[R] \f[B]E\f[R] +\f[B]print\f[R] \f[B]E\f[R] \f[B],\f[R] ... +\f[B],\f[R] \f[B]E\f[R] .IP "15." 4 \f[B]I()\f[R], \f[B]I(E)\f[R], \f[B]I(E, E)\f[R], and so on, where \f[B]I\f[R] is an identifier for a \f[B]void\f[R] function (see the @@ -953,62 +1044,22 @@ Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. .SS Print Statement .PP -The \[lq]expressions\[rq] in a \f[B]print\f[R] statement may also be +The \[dq]expressions\[dq] in a \f[B]print\f[R] statement may also be strings. If they are, there are backslash escape sequences that are interpreted specially. What those sequences are, and what they cause to be printed, are shown below: .PP -.TS -tab(@); -l l. -T{ -\f[B]\[rs]a\f[R] -T}@T{ -\f[B]\[rs]a\f[R] -T} -T{ -\f[B]\[rs]b\f[R] -T}@T{ -\f[B]\[rs]b\f[R] -T} -T{ -\f[B]\[rs]\[rs]\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]e\f[R] -T}@T{ -\f[B]\[rs]\f[R] -T} -T{ -\f[B]\[rs]f\f[R] -T}@T{ -\f[B]\[rs]f\f[R] -T} -T{ -\f[B]\[rs]n\f[R] -T}@T{ -\f[B]\[rs]n\f[R] -T} -T{ -\f[B]\[rs]q\f[R] -T}@T{ -\f[B]\[dq]\f[R] -T} -T{ -\f[B]\[rs]r\f[R] -T}@T{ -\f[B]\[rs]r\f[R] -T} -T{ -\f[B]\[rs]t\f[R] -T}@T{ -\f[B]\[rs]t\f[R] -T} -.TE + * * * * * +.PP +\f[B]\[rs]a\f[R] \f[B]\[rs]a\f[R] \f[B]\[rs]b\f[R] \f[B]\[rs]b\f[R] +\f[B]\[rs]\[rs]\f[R] \f[B]\[rs]\f[R] \f[B]\[rs]e\f[R] \f[B]\[rs]\f[R] +\f[B]\[rs]f\f[R] \f[B]\[rs]f\f[R] \f[B]\[rs]n\f[R] \f[B]\[rs]n\f[R] +\f[B]\[rs]q\f[R] \f[B]\[dq]\f[R] \f[B]\[rs]r\f[R] \f[B]\[rs]r\f[R] +\f[B]\[rs]t\f[R] \f[B]\[rs]t\f[R] +.PP + * * * * * .PP Any other character following a backslash causes the backslash and character to be printed as-is. @@ -1104,9 +1155,9 @@ Void functions can only use the first two \f[B]return\f[R] statements listed above. They can also omit the return statement entirely. .PP -The word \[lq]void\[rq] is not treated as a keyword; it is still +The word \[dq]void\[dq] is not treated as a keyword; it is still possible to have variables, arrays, and functions named \f[B]void\f[R]. -The word \[lq]void\[rq] is only treated specially right after the +The word \[dq]void\[dq] is only treated specially right after the \f[B]define\f[R] keyword. .PP This is a \f[B]non-portable extension\f[R]. @@ -1141,55 +1192,74 @@ are given. The standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) defines the following functions for the math library: -.TP +.PP \f[B]s(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]c(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l(x)\f[R] -Returns the natural logarithm of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the natural logarithm of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]e(x)\f[R] -Returns the mathematical constant \f[B]e\f[R] raised to the power of +.PP +: Returns the mathematical constant \f[B]e\f[R] raised to the power of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]j(x, n)\f[R] -Returns the bessel integer order \f[B]n\f[R] (truncated) of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE +: Returns the bessel integer order \f[B]n\f[R] (truncated) of +\f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .SS Extended Library .PP The extended library is \f[I]not\f[R] loaded when the @@ -1198,99 +1268,126 @@ options are given since they are not part of the library defined by the standard (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html). .PP The extended library is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p(x, y)\f[R] -Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if \f[B]y\f[R] -is not an integer, and returns the result to the current +.PP +: Calculates \f[B]x\f[R] to the power of \f[B]y\f[R], even if +\f[B]y\f[R] is not an integer, and returns the result to the current \f[B]scale\f[R]. -.RS +.IP +.nf +\f[C] +It is an error if **y** is negative and **x** is **0**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -It is an error if \f[B]y\f[R] is negative and \f[B]x\f[R] is -\f[B]0\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round half away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero). -.TP +.PP \f[B]ceil(x, p)\f[R] -Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to +.PP +: Returns \f[B]x\f[R] rounded to \f[B]p\f[R] decimal places according to the rounding mode round away from \f[B]0\f[R] (https://en.wikipedia.org/wiki/Rounding#Rounding_away_from_zero). -.TP +.PP \f[B]f(x)\f[R] -Returns the factorial of the truncated absolute value of \f[B]x\f[R]. -.TP +.PP +: Returns the factorial of the truncated absolute value of \f[B]x\f[R]. +.PP \f[B]perm(n, k)\f[R] -Returns the permutation of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the permutation of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]comb(n, k)\f[R] -Returns the combination of the truncated absolute value of \f[B]n\f[R] +.PP +: Returns the combination of the truncated absolute value of \f[B]n\f[R] of the truncated absolute value of \f[B]k\f[R], if \f[B]k <= n\f[R]. If not, it returns \f[B]0\f[R]. -.TP +.PP \f[B]l2(x)\f[R] -Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]2\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]l10(x)\f[R] -Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]10\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]log(x, b)\f[R] -Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the logarithm base \f[B]b\f[R] of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]cbrt(x)\f[R] -Returns the cube root of \f[B]x\f[R]. -.TP +.PP +: Returns the cube root of \f[B]x\f[R]. +.PP \f[B]root(x, n)\f[R] -Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and returns -the \f[B]r\f[R]th root of \f[B]x\f[R] to the current \f[B]scale\f[R]. -.RS .PP -If \f[B]r\f[R] is \f[B]0\f[R] or negative, this raises an error and -causes bc(1) to reset (see the \f[B]RESET\f[R] section). -It also raises an error and causes bc(1) to reset if \f[B]r\f[R] is even -and \f[B]x\f[R] is negative. -.RE -.TP +: Calculates the truncated value of \f[B]n\f[R], \f[B]r\f[R], and +returns the \f[B]r\f[R]th root of \f[B]x\f[R] to the current +\f[B]scale\f[R]. +.IP +.nf +\f[C] +If **r** is **0** or negative, this raises an error and causes bc(1) to +reset (see the **RESET** section). It also raises an error and causes bc(1) +to reset if **r** is even and **x** is negative. +\f[R] +.fi +.PP \f[B]pi(p)\f[R] -Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns \f[B]pi\f[R] to \f[B]p\f[R] decimal places. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]t(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]a2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1303,60 +1400,75 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]sin(x)\f[R] -Returns the sine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]s(x)\f[R]. +: Returns the sine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **s(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]cos(x)\f[R] -Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -This is an alias of \f[B]c(x)\f[R]. +: Returns the cosine of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +This is an alias of **c(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]tan(x)\f[R] -Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. -.RS .PP -If \f[B]x\f[R] is equal to \f[B]1\f[R] or \f[B]-1\f[R], this raises an -error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). +: Returns the tangent of \f[B]x\f[R], which is assumed to be in radians. +.IP +.nf +\f[C] +If **x** is equal to **1** or **-1**, this raises an error and causes bc(1) +to reset (see the **RESET** section). + +This is an alias of **t(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is an alias of \f[B]t(x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan(x)\f[R] -Returns the arctangent of \f[B]x\f[R], in radians. -.RS .PP -This is an alias of \f[B]a(x)\f[R]. +: Returns the arctangent of \f[B]x\f[R], in radians. +.IP +.nf +\f[C] +This is an alias of **a(x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]atan2(y, x)\f[R] -Returns the arctangent of \f[B]y/x\f[R], in radians. +.PP +: Returns the arctangent of \f[B]y/x\f[R], in radians. If both \f[B]y\f[R] and \f[B]x\f[R] are equal to \f[B]0\f[R], it raises an error and causes bc(1) to reset (see the \f[B]RESET\f[R] section). Otherwise, if \f[B]x\f[R] is greater than \f[B]0\f[R], it returns @@ -1369,302 +1481,367 @@ If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is greater than \f[B]0\f[R], it returns \f[B]pi/2\f[R]. If \f[B]x\f[R] is equal to \f[B]0\f[R], and \f[B]y\f[R] is less than \f[B]0\f[R], it returns \f[B]-pi/2\f[R]. -.RS +.IP +.nf +\f[C] +This function is the same as the **atan2()** function in many programming +languages. + +This is an alias of **a2(y, x)**. + +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi .PP -This function is the same as the \f[B]atan2()\f[R] function in many -programming languages. -.PP -This is an alias of \f[B]a2(y, x)\f[R]. -.PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP \f[B]r2d(x)\f[R] -Converts \f[B]x\f[R] from radians to degrees and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from radians to degrees and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]d2r(x)\f[R] -Converts \f[B]x\f[R] from degrees to radians and returns the result. -.RS .PP -This is a transcendental function (see the \f[I]Transcendental -Functions\f[R] subsection below). -.RE -.TP +: Converts \f[B]x\f[R] from degrees to radians and returns the result. +.IP +.nf +\f[C] +This is a transcendental function (see the *Transcendental Functions* +subsection below). +\f[R] +.fi +.PP \f[B]frand(p)\f[R] -Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and +.PP +: Generates a pseudo-random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R] (exclusive) with the number of decimal digits after the decimal point equal to the truncated absolute value of \f[B]p\f[R]. If \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]. If \f[B]p\f[R] is \f[B]0\f[R], then \f[B]0\f[R] is returned, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.TP +.PP \f[B]ifrand(i, p)\f[R] -Generates a pseudo-random number that is between \f[B]0\f[R] (inclusive) -and the truncated absolute value of \f[B]i\f[R] (exclusive) with the -number of decimal digits after the decimal point equal to the truncated -absolute value of \f[B]p\f[R]. +.PP +: Generates a pseudo-random number that is between \f[B]0\f[R] +(inclusive) and the truncated absolute value of \f[B]i\f[R] (exclusive) +with the number of decimal digits after the decimal point equal to the +truncated absolute value of \f[B]p\f[R]. If the absolute value of \f[B]i\f[R] is greater than or equal to \f[B]2\f[R], and \f[B]p\f[R] is not \f[B]0\f[R], then calling this function will change the value of \f[B]seed\f[R]; otherwise, \f[B]0\f[R] is returned and \f[B]seed\f[R] is not changed. -.TP +.PP \f[B]srand(x)\f[R] -Returns \f[B]x\f[R] with its sign flipped with probability +.PP +: Returns \f[B]x\f[R] with its sign flipped with probability \f[B]0.5\f[R]. In other words, it randomizes the sign of \f[B]x\f[R]. -.TP +.PP \f[B]brand()\f[R] -Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). -.TP +.PP +: Returns a random boolean value (either \f[B]0\f[R] or \f[B]1\f[R]). +.PP \f[B]ubytes(x)\f[R] -Returns the numbers of unsigned integer bytes required to hold the +.PP +: Returns the numbers of unsigned integer bytes required to hold the truncated absolute value of \f[B]x\f[R]. -.TP +.PP \f[B]sbytes(x)\f[R] -Returns the numbers of signed, two\[cq]s-complement integer bytes +.PP +: Returns the numbers of signed, two\[aq]s-complement integer bytes required to hold the truncated value of \f[B]x\f[R]. -.TP +.PP \f[B]hex(x)\f[R] -Outputs the hexadecimal (base \f[B]16\f[R]) representation of +.PP +: Outputs the hexadecimal (base \f[B]16\f[R]) representation of \f[B]x\f[R]. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary(x)\f[R] -Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the binary (base \f[B]2\f[R]) representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]output(x, b)\f[R] -Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP +: Outputs the base \f[B]b\f[R] representation of \f[B]x\f[R]. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi +.PP \f[B]uint(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in as few power of two bytes as possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in as few power of two bytes as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or is negative, an error message is printed +instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or is negative, an error message is -printed instead, but bc(1) is not reset (see the \f[B]RESET\f[R] -section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in as few power of two bytes as -possible. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in as few power of two bytes +as possible. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, an error message is printed instead, but bc(1) +is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, an error message is printed instead, -but bc(1) is not reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uintn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **n** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]n\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]intn(x, n)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]n\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]n\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **n** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]n\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **1** byte, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]1\f[R] byte, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int8(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]1\f[R] byte. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]1\f[R] byte. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **1** byte, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]1\f[R] byte, an -error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **2** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]2\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int16(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]2\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]2\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **2** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]2\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **4** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]4\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int32(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]4\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]4\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **4** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]4\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]uint64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -an unsigned integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as an unsigned integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer, is negative, or cannot fit into **8** bytes, an +error message is printed instead, but bc(1) is not reset (see the **RESET** +section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer, is negative, or cannot fit into -\f[B]8\f[R] bytes, an error message is printed instead, but bc(1) is not -reset (see the \f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]int64(x)\f[R] -Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] as -a signed, two\[cq]s-complement integer in \f[B]8\f[R] bytes. +.PP +: Outputs the representation, in binary and hexadecimal, of \f[B]x\f[R] +as a signed, two\[aq]s-complement integer in \f[B]8\f[R] bytes. Both outputs are split into bytes separated by spaces. -.RS +.IP +.nf +\f[C] +If **x** is not an integer or cannot fit into **8** bytes, an error message +is printed instead, but bc(1) is not reset (see the **RESET** section). + +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -If \f[B]x\f[R] is not an integer or cannot fit into \f[B]8\f[R] bytes, -an error message is printed instead, but bc(1) is not reset (see the -\f[B]RESET\f[R] section). -.PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]hex_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in hexadecimal using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]binary_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in binary using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_uint(x, n)\f[R] -Outputs the representation of the truncated absolute value of +.PP +: Outputs the representation of the truncated absolute value of \f[B]x\f[R] as an unsigned integer in the current \f[B]obase\f[R] (see the \f[B]SYNTAX\f[R] section) using \f[B]n\f[R] bytes. Not all of the value will be output if \f[B]n\f[R] is too small. -.RS +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE -.TP \f[B]output_byte(x, i)\f[R] -Outputs byte \f[B]i\f[R] of the truncated absolute value of \f[B]x\f[R], -where \f[B]0\f[R] is the least significant byte and \f[B]number_of_bytes -- 1\f[R] is the most significant byte. -.RS .PP -This is a \f[B]void\f[R] function (see the \f[I]Void Functions\f[R] -subsection of the \f[B]FUNCTIONS\f[R] section). -.RE +: Outputs byte \f[B]i\f[R] of the truncated absolute value of +\f[B]x\f[R], where \f[B]0\f[R] is the least significant byte and +\f[B]number_of_bytes - 1\f[R] is the most significant byte. +.IP +.nf +\f[C] +This is a **void** function (see the *Void Functions* subsection of the +**FUNCTIONS** section). +\f[R] +.fi .SS Transcendental Functions .PP All transcendental functions can return slightly inaccurate results (up @@ -1768,64 +1945,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bc(1): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]rand()\f[R] +.PP +: The maximum integer (inclusive) returned by the \f[B]rand()\f[R] operand. Set at \f[B]2\[ha]BC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP The actual values can be queried with the \f[B]limits\f[R] statement. @@ -1837,42 +2027,44 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP bc(1) recognizes the following environment variables: -.TP +.PP \f[B]POSIXLY_CORRECT\f[R] -If this variable exists (no matter the contents), bc(1) behaves as if +.PP +: If this variable exists (no matter the contents), bc(1) behaves as if the \f[B]-s\f[R] option was given. -.TP +.PP \f[B]BC_ENV_ARGS\f[R] -This is another way to give command-line arguments to bc(1). +.PP +: This is another way to give command-line arguments to bc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]BC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time bc(1) runs. -.RS +.IP +.nf +\f[C] +The code that parses **BC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some bc file.bc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]bc\[rs]\[dq] file.bc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]bc\[aq] file.bc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **BC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]BC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some bc file.bc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]bc\[dq] file.bc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `bc' file.bc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]BC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]BC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), bc(1) will output lines to that length, including the backslash (\f[B]\[rs]\f[R]). @@ -1880,68 +2072,76 @@ The default line length is \f[B]70\f[R]. .SH EXIT STATUS .PP bc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**\[rs]<\[rs]<**), and right shift (**\[rs]>\[rs]>**) +operators and their corresponding assignment operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]<<\f[R]), and right shift (\f[B]>>\f[R]) operators and their -corresponding assignment operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, using a token -where it is invalid, giving an invalid expression, giving an invalid -print statement, giving an invalid function definition, attempting to -assign to an expression that is not a named expression (see the -\f[I]Named Expressions\f[R] subsection of the \f[B]SYNTAX\f[R] section), -giving an invalid \f[B]auto\f[R] list, having a duplicate -\f[B]auto\f[R]/function parameter, failing to find the end of a code -block, attempting to return a value from a \f[B]void\f[R] function, -attempting to use a variable as a reference, and using any extensions -when the option \f[B]-s\f[R] or any equivalents were given. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, using a token where it is invalid, +giving an invalid expression, giving an invalid print statement, giving an +invalid function definition, attempting to assign to an expression that is +not a named expression (see the *Named Expressions* subsection of the +**SYNTAX** section), giving an invalid **auto** list, having a duplicate +**auto**/function parameter, failing to find the end of a code block, +attempting to return a value from a **void** function, attempting to use a +variable as a reference, and using any extensions when the option **-s** or +any equivalents were given. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, passing the wrong number of +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, passing the wrong number of arguments to functions, attempting to call an undefined function, and -attempting to use a \f[B]void\f[R] function call as a value in an -expression. -.RE -.TP -\f[B]4\f[R] -A fatal error occurred. -.RS +attempting to use a **void** function call as a value in an expression. +\f[R] +.fi .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (bc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +\f[B]4\f[R] +.PP +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (bc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, bc(1) always exits and returns \f[B]4\f[R], no matter what mode bc(1) is in. @@ -1971,7 +2171,7 @@ In interactive mode, bc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, bc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, bc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1991,7 +2191,7 @@ If bc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If bc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If bc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/bc/P.1.md b/manuals/bc/P.1.md index 489af865475c..4434f7c803a2 100644 --- a/manuals/bc/P.1.md +++ b/manuals/bc/P.1.md @@ -34,7 +34,7 @@ bc - arbitrary-precision decimal arithmetic language and calculator # SYNOPSIS -**bc** [**-ghilPqsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**bc** [**-ghilPqRsvVw**] [**-\-global-stacks**] [**-\-help**] [**-\-interactive**] [**-\-mathlib**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-quiet**] [**-\-standard**] [**-\-warn**] [**-\-version**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -146,6 +146,12 @@ The following are the options that bc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Because bc(1) was built without support for prompts, this option is a no-op. + + This is a **non-portable extension**. + **-q**, **-\-quiet** : This option is for compatibility with the [GNU bc(1)][2]; it is a no-op. diff --git a/manuals/bcl.3 b/manuals/bcl.3 index d83a2d3ad2e5..550ea118431e 100644 --- a/manuals/bcl.3 +++ b/manuals/bcl.3 @@ -25,7 +25,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "BCL" "3" "March 2021" "Gavin D. Howard" "Libraries Manual" +.TH "BCL" "3" "April 2021" "Gavin D. Howard" "Libraries Manual" .SH NAME .PP bcl - library of arbitrary precision decimal arithmetic @@ -40,22 +40,22 @@ Link with \f[I]-lbcl\f[R]. This procedure will allow clients to use signals to interrupt computations running in bcl(3). .PP -\f[B]void bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]void bcl_handleSignal(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]bool bcl_running(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]bool bcl_running(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .SS Setup .PP These items allow clients to set up bcl(3). .PP -\f[B]BclError bcl_init(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]BclError bcl_init(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]void bcl_free(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]void bcl_free(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]bool bcl_abortOnFatalError(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]bool bcl_abortOnFatalError(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]void bcl_setAbortOnFatalError(bool\f[R] \f[I]abrt\f[R]\f[B]);\f[R] +\f[B]void bcl_setAbortOnFatalError(bool\f[R] \f[I]abrt\f[R]**);** .PP -\f[B]void bcl_gc(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]void bcl_gc(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .SS Contexts .PP These items will allow clients to handle contexts, which are isolated @@ -66,39 +66,39 @@ This allows more than one client to use bcl(3) in the same program. .PP \f[B]typedef struct BclCtxt* BclContext;\f[R] .PP -\f[B]BclContext bcl_ctxt_create(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]BclContext bcl_ctxt_create(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]void bcl_ctxt_free(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\f[R] +\f[B]void bcl_ctxt_free(BclContext\f[R] \f[I]ctxt\f[R]**);** .PP -\f[B]BclError bcl_pushContext(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\f[R] +\f[B]BclError bcl_pushContext(BclContext\f[R] \f[I]ctxt\f[R]**);** .PP -\f[B]void bcl_popContext(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]void bcl_popContext(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]BclContext bcl_context(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]BclContext bcl_context(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]void bcl_ctxt_freeNums(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\f[R] +\f[B]void bcl_ctxt_freeNums(BclContext\f[R] \f[I]ctxt\f[R]**);** .PP -\f[B]size_t bcl_ctxt_scale(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\f[R] +\f[B]size_t bcl_ctxt_scale(BclContext\f[R] \f[I]ctxt\f[R]**);** .PP -\f[B]void bcl_ctxt_setScale(BclContext\f[R] \f[I]ctxt\f[R]\f[B], -size_t\f[R] \f[I]scale\f[R]\f[B]);\f[R] +\f[B]void bcl_ctxt_setScale(BclContext\f[R] \f[I]ctxt\f[R]**, size_t** +\f[I]scale\f[R]**);** .PP -\f[B]size_t bcl_ctxt_ibase(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\f[R] +\f[B]size_t bcl_ctxt_ibase(BclContext\f[R] \f[I]ctxt\f[R]**);** .PP -\f[B]void bcl_ctxt_setIbase(BclContext\f[R] \f[I]ctxt\f[R]\f[B], -size_t\f[R] \f[I]ibase\f[R]\f[B]);\f[R] +\f[B]void bcl_ctxt_setIbase(BclContext\f[R] \f[I]ctxt\f[R]**, size_t** +\f[I]ibase\f[R]**);** .PP -\f[B]size_t bcl_ctxt_obase(BclContext\f[R] \f[I]ctxt\f[R]\f[B]);\f[R] +\f[B]size_t bcl_ctxt_obase(BclContext\f[R] \f[I]ctxt\f[R]**);** .PP -\f[B]void bcl_ctxt_setObase(BclContext\f[R] \f[I]ctxt\f[R]\f[B], -size_t\f[R] \f[I]obase\f[R]\f[B]);\f[R] +\f[B]void bcl_ctxt_setObase(BclContext\f[R] \f[I]ctxt\f[R]**, size_t** +\f[I]obase\f[R]**);** .SS Errors .PP These items allow clients to handle errors. .PP \f[B]typedef enum BclError BclError;\f[R] .PP -\f[B]BclError bcl_err(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R] +\f[B]BclError bcl_err(BclNumber\f[R] \f[I]n\f[R]**);** .SS Numbers .PP These items allow clients to manipulate and query the @@ -106,86 +106,85 @@ arbitrary-precision numbers managed by bcl(3). .PP \f[B]typedef struct { size_t i; } BclNumber;\f[R] .PP -\f[B]BclNumber bcl_num_create(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_num_create(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]void bcl_num_free(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R] +\f[B]void bcl_num_free(BclNumber\f[R] \f[I]n\f[R]**);** .PP -\f[B]bool bcl_num_neg(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R] +\f[B]bool bcl_num_neg(BclNumber\f[R] \f[I]n\f[R]**);** .PP -\f[B]void bcl_num_setNeg(BclNumber\f[R] \f[I]n\f[R]\f[B], bool\f[R] -\f[I]neg\f[R]\f[B]);\f[R] +\f[B]void bcl_num_setNeg(BclNumber\f[R] \f[I]n\f[R]**, bool** +\f[I]neg\f[R]**);** .PP -\f[B]size_t bcl_num_scale(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R] +\f[B]size_t bcl_num_scale(BclNumber\f[R] \f[I]n\f[R]**);** .PP -\f[B]BclError bcl_num_setScale(BclNumber\f[R] \f[I]n\f[R]\f[B], -size_t\f[R] \f[I]scale\f[R]\f[B]);\f[R] +\f[B]BclError bcl_num_setScale(BclNumber\f[R] \f[I]n\f[R]**, size_t** +\f[I]scale\f[R]**);** .PP -\f[B]size_t bcl_num_len(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R] +\f[B]size_t bcl_num_len(BclNumber\f[R] \f[I]n\f[R]**);** .SS Conversion .PP These items allow clients to convert numbers into and from strings and integers. .PP -\f[B]BclNumber bcl_parse(const char *restrict\f[R] -\f[I]val\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_parse(const char *restrict\f[R] \f[I]val\f[R]**);** .PP -\f[B]char* bcl_string(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R] +\f[B]char* bcl_string(BclNumber\f[R] \f[I]n\f[R]**);** .PP -\f[B]BclError bcl_bigdig(BclNumber\f[R] \f[I]n\f[R]\f[B], BclBigDig -*\f[R]\f[I]result\f[R]\f[B]);\f[R] +\f[B]BclError bcl_bigdig(BclNumber\f[R] \f[I]n\f[R]**, BclBigDig +*\f[I]\f[BI]result\f[I]\f[R]);** .PP -\f[B]BclNumber bcl_bigdig2num(BclBigDig\f[R] \f[I]val\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_bigdig2num(BclBigDig\f[R] \f[I]val\f[R]**);** .SS Math .PP These items allow clients to run math on numbers. .PP -\f[B]BclNumber bcl_add(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] -\f[I]b\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_add(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**);** .PP -\f[B]BclNumber bcl_sub(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] -\f[I]b\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_sub(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**);** .PP -\f[B]BclNumber bcl_mul(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] -\f[I]b\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_mul(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**);** .PP -\f[B]BclNumber bcl_div(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] -\f[I]b\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_div(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**);** .PP -\f[B]BclNumber bcl_mod(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] -\f[I]b\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_mod(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**);** .PP -\f[B]BclNumber bcl_pow(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] -\f[I]b\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_pow(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**);** .PP -\f[B]BclNumber bcl_lshift(BclNumber\f[R] \f[I]a\f[R]\f[B], -BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_lshift(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**);** .PP -\f[B]BclNumber bcl_rshift(BclNumber\f[R] \f[I]a\f[R]\f[B], -BclNumber\f[R] \f[I]b\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_rshift(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**);** .PP -\f[B]BclNumber bcl_sqrt(BclNumber\f[R] \f[I]a\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_sqrt(BclNumber\f[R] \f[I]a\f[R]**);** .PP -\f[B]BclError bcl_divmod(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] -\f[I]b\f[R]\f[B], BclNumber *\f[R]\f[I]c\f[R]\f[B], BclNumber -*\f[R]\f[I]d\f[R]\f[B]);\f[R] +\f[B]BclError bcl_divmod(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**, BclNumber *\f[I]\f[BI]c\f[I]\f[R], BclNumber +*\f[I]\f[BI]d\f[I]\f[R]);** .PP -\f[B]BclNumber bcl_modexp(BclNumber\f[R] \f[I]a\f[R]\f[B], -BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber\f[R] \f[I]c\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_modexp(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**, BclNumber** \f[I]c\f[R]**);** .SS Miscellaneous .PP These items are miscellaneous. .PP -\f[B]void bcl_zero(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R] +\f[B]void bcl_zero(BclNumber\f[R] \f[I]n\f[R]**);** .PP -\f[B]void bcl_one(BclNumber\f[R] \f[I]n\f[R]\f[B]);\f[R] +\f[B]void bcl_one(BclNumber\f[R] \f[I]n\f[R]**);** .PP -\f[B]ssize_t bcl_cmp(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] -\f[I]b\f[R]\f[B]);\f[R] +\f[B]ssize_t bcl_cmp(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**);** .PP -\f[B]BclError bcl_copy(BclNumber\f[R] \f[I]d\f[R]\f[B], BclNumber\f[R] -\f[I]s\f[R]\f[B]);\f[R] +\f[B]BclError bcl_copy(BclNumber\f[R] \f[I]d\f[R]**, BclNumber** +\f[I]s\f[R]**);** .PP -\f[B]BclNumber bcl_dup(BclNumber\f[R] \f[I]s\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_dup(BclNumber\f[R] \f[I]s\f[R]**);** .SS Pseudo-Random Number Generator .PP These items allow clients to manipulate the seeded pseudo-random number @@ -199,27 +198,25 @@ generator in bcl(3). .PP \f[B]typedef unsigned long BclRandInt;\f[R] .PP -\f[B]BclNumber bcl_irand(BclNumber\f[R] \f[I]a\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_irand(BclNumber\f[R] \f[I]a\f[R]**);** .PP -\f[B]BclNumber bcl_frand(size_t\f[R] \f[I]places\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_frand(size_t\f[R] \f[I]places\f[R]**);** .PP -\f[B]BclNumber bcl_ifrand(BclNumber\f[R] \f[I]a\f[R]\f[B], size_t\f[R] -\f[I]places\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_ifrand(BclNumber\f[R] \f[I]a\f[R]**, size_t** +\f[I]places\f[R]**);** .PP -\f[B]BclError bcl_rand_seedWithNum(BclNumber\f[R] -\f[I]n\f[R]\f[B]);\f[R] +\f[B]BclError bcl_rand_seedWithNum(BclNumber\f[R] \f[I]n\f[R]**);** .PP \f[B]BclError bcl_rand_seed(unsigned char\f[R] -\f[I]seed\f[R]\f[B][\f[R]\f[I]BC_SEED_SIZE\f[R]\f[B]]);\f[R] +\f[I]seed\f[R]**[\f[I]\f[BI]BC_SEED_SIZE\f[I]\f[R]]);** .PP -\f[B]void bcl_rand_reseed(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]void bcl_rand_reseed(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]BclNumber bcl_rand_seed2num(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]BclNumber bcl_rand_seed2num(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]BclRandInt bcl_rand_int(\f[R]\f[I]void\f[R]\f[B]);\f[R] +\f[B]BclRandInt bcl_rand_int(\f[BI]\f[I]void\f[BI]\f[B]);\f[R] .PP -\f[B]BclRandInt bcl_rand_bounded(BclRandInt\f[R] -\f[I]bound\f[R]\f[B]);\f[R] +\f[B]BclRandInt bcl_rand_bounded(BclRandInt\f[R] \f[I]bound\f[R]**);** .SH DESCRIPTION .PP bcl(3) is a library that implements arbitrary-precision decimal math, as @@ -228,278 +225,329 @@ POSIX (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) in bc(1). .PP bcl(3) is async-signal-safe if -\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] is used properly. +\f[B]bcl_handleSignal(\f[BI]\f[I]void\f[BI]\f[B])\f[R] is used properly. (See the \f[B]SIGNAL HANDLING\f[R] section.) .PP All of the items in its interface are described below. See the documentation for each function for what each function can return. .SS Signals -.TP -\f[B]void bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] -An async-signal-safe function that can be called from a signal handler. +.PP +\f[B]void bcl_handleSignal(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: An async-signal-safe function that can be called from a signal +handler. If called from a signal handler on the same thread as any executing bcl(3) functions, it will interrupt the functions and force them to return early. It is undefined behavior if this function is called from a thread that is \f[I]not\f[R] executing any bcl(3) functions while any bcl(3) functions are executing. -.RS -.PP -If execution \f[I]is\f[R] interrupted, -\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] does \f[I]not\f[R] +.IP +.nf +\f[C] +If execution *is* interrupted, **bcl_handleSignal(***void***)** does *not* return to its caller. + +See the **SIGNAL HANDLING** section. +\f[R] +.fi .PP -See the \f[B]SIGNAL HANDLING\f[R] section. -.RE -.TP -\f[B]bool bcl_running(\f[R]\f[I]void\f[R]\f[B])\f[R] -An async-signal-safe function that can be called from a signal handler. +\f[B]bool bcl_running(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: An async-signal-safe function that can be called from a signal +handler. It will return \f[B]true\f[R] if any bcl(3) procedures are running, which means it is safe to call -\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R]. +\f[B]bcl_handleSignal(\f[BI]\f[I]void\f[BI]\f[B])\f[R]. Otherwise, it returns \f[B]false\f[R]. -.RS -.PP -See the \f[B]SIGNAL HANDLING\f[R] section. -.RE +.IP +.nf +\f[C] +See the **SIGNAL HANDLING** section. +\f[R] +.fi .SS Setup -.TP -\f[B]BclError bcl_init(\f[R]\f[I]void\f[R]\f[B])\f[R] -Initializes this library. +.PP +\f[B]BclError bcl_init(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: Initializes this library. This function can be called multiple times, but each call must be -matched by a call to \f[B]bcl_free(\f[R]\f[I]void\f[R]\f[B])\f[R]. +matched by a call to \f[B]bcl_free(\f[BI]\f[I]void\f[BI]\f[B])\f[R]. This is to make it possible for multiple libraries and applications to initialize bcl(3) without problem. -.RS +.IP +.nf +\f[C] +If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this +function can return: + +* **BCL_ERROR_FATAL_ALLOC_ERR** + +This function must be the first one clients call. Calling any other +function without calling this one first is undefined behavior. +\f[R] +.fi .PP -If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned. -Otherwise, this function can return: -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] +\f[B]void bcl_free(\f[BI]\f[I]void\f[BI]\f[B])\f[R] .PP -This function must be the first one clients call. -Calling any other function without calling this one first is undefined -behavior. -.RE -.TP -\f[B]void bcl_free(\f[R]\f[I]void\f[R]\f[B])\f[R] -Decrements bcl(3)\[cq]s reference count and frees the data associated +: Decrements bcl(3)\[aq]s reference count and frees the data associated with it if the reference count is \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +This function must be the last one clients call. Calling this function +before calling any other function is undefined behavior. +\f[R] +.fi .PP -This function must be the last one clients call. -Calling this function before calling any other function is undefined -behavior. -.RE -.TP -\f[B]bool bcl_abortOnFatalError(\f[R]\f[I]void\f[R]\f[B])\f[R] -Queries and returns the current state of calling \f[B]abort()\f[R] on +\f[B]bool bcl_abortOnFatalError(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: Queries and returns the current state of calling \f[B]abort()\f[R] on fatal errors. If \f[B]true\f[R] is returned, bcl(3) will cause a \f[B]SIGABRT\f[R] if a fatal error occurs. -.RS -.PP +.IP +.nf +\f[C] If activated, clients do not need to check for fatal errors. -.RE -.TP -\f[B]void bcl_setAbortOnFatalError(bool\f[R] \f[I]abrt\f[R]\f[B])\f[R] -Sets the state of calling \f[B]abort()\f[R] on fatal errors. +\f[R] +.fi +.PP +\f[B]void bcl_setAbortOnFatalError(bool\f[R] \f[I]abrt\f[R]**)** +.PP +: Sets the state of calling \f[B]abort()\f[R] on fatal errors. If \f[I]abrt\f[R] is \f[B]false\f[R], bcl(3) will not cause a \f[B]SIGABRT\f[R] on fatal errors after the call. If \f[I]abrt\f[R] is \f[B]true\f[R], bcl(3) will cause a \f[B]SIGABRT\f[R] on fatal errors after the call. -.RS -.PP +.IP +.nf +\f[C] If activated, clients do not need to check for fatal errors. -.RE -.TP -\f[B]void bcl_gc(\f[R]\f[I]void\f[R]\f[B])\f[R] -Garbage collects cached instances of arbitrary-precision numbers. +\f[R] +.fi +.PP +\f[B]void bcl_gc(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: Garbage collects cached instances of arbitrary-precision numbers. This only frees the memory of numbers that are \f[I]not\f[R] in use, so it is safe to call at any time. .SS Contexts .PP All procedures that take a \f[B]BclContext\f[R] parameter a require a valid context as an argument. -.TP +.PP \f[B]struct BclCtxt\f[R] -A forward declaration for a hidden \f[B]struct\f[R] type. +.PP +: A forward declaration for a hidden \f[B]struct\f[R] type. Clients cannot access the internals of the \f[B]struct\f[R] type directly. All interactions with the type are done through pointers. See \f[B]BclContext\f[R] below. -.TP +.PP \f[B]BclContext\f[R] -A typedef to a pointer of \f[B]struct BclCtxt\f[R]. +.PP +: A typedef to a pointer of \f[B]struct BclCtxt\f[R]. This is the only handle clients can get to \f[B]struct BclCtxt\f[R]. -.RS -.PP -A \f[B]BclContext\f[R] contains the values \f[B]scale\f[R], -\f[B]ibase\f[R], and \f[B]obase\f[R], as well as a list of numbers. -.PP -\f[B]scale\f[R] is a value used to control how many decimal places -calculations should use. -A value of \f[B]0\f[R] means that calculations are done on integers +.IP +.nf +\f[C] +A **BclContext** contains the values **scale**, **ibase**, and **obase**, as +well as a list of numbers. + +**scale** is a value used to control how many decimal places calculations +should use. A value of **0** means that calculations are done on integers only, where applicable, and a value of 20, for example, means that all -applicable calculations return results with 20 decimal places. -The default is \f[B]0\f[R]. +applicable calculations return results with 20 decimal places. The default +is **0**. + +**ibase** is a value used to control the input base. The minimum **ibase** +is **2**, and the maximum is **36**. If **ibase** is **2**, numbers are +parsed as though they are in binary, and any digits larger than **1** are +clamped. Likewise, a value of **10** means that numbers are parsed as though +they are decimal, and any larger digits are clamped. The default is **10**. + +**obase** is a value used to control the output base. The minimum **obase** +is **0** and the maximum is **BC_BASE_MAX** (see the **LIMITS** section). + +Numbers created in one context are not valid in another context. It is +undefined behavior to use a number created in a different context. Contexts +are meant to isolate the numbers used by different clients in the same +application. +\f[R] +.fi .PP -\f[B]ibase\f[R] is a value used to control the input base. -The minimum \f[B]ibase\f[R] is \f[B]2\f[R], and the maximum is -\f[B]36\f[R]. -If \f[B]ibase\f[R] is \f[B]2\f[R], numbers are parsed as though they are -in binary, and any digits larger than \f[B]1\f[R] are clamped. -Likewise, a value of \f[B]10\f[R] means that numbers are parsed as -though they are decimal, and any larger digits are clamped. -The default is \f[B]10\f[R]. +\f[B]BclContext bcl_ctxt_create(\f[BI]\f[I]void\f[BI]\f[B])\f[R] .PP -\f[B]obase\f[R] is a value used to control the output base. -The minimum \f[B]obase\f[R] is \f[B]0\f[R] and the maximum is -\f[B]BC_BASE_MAX\f[R] (see the \f[B]LIMITS\f[R] section). -.PP -Numbers created in one context are not valid in another context. -It is undefined behavior to use a number created in a different context. -Contexts are meant to isolate the numbers used by different clients in -the same application. -.RE -.TP -\f[B]BclContext bcl_ctxt_create(\f[R]\f[I]void\f[R]\f[B])\f[R] -Creates a context and returns it. +: Creates a context and returns it. Returns \f[B]NULL\f[R] if there was an error. -.TP -\f[B]void bcl_ctxt_free(BclContext\f[R] \f[I]ctxt\f[R]\f[B])\f[R] -Frees \f[I]ctxt\f[R], after which it is no longer valid. +.PP +\f[B]void bcl_ctxt_free(BclContext\f[R] \f[I]ctxt\f[R]**)** +.PP +: Frees \f[I]ctxt\f[R], after which it is no longer valid. It is undefined behavior to attempt to use an invalid context. -.TP -\f[B]BclError bcl_pushContext(BclContext\f[R] \f[I]ctxt\f[R]\f[B])\f[R] -Pushes \f[I]ctxt\f[R] onto bcl(3)\[cq]s stack of contexts. +.PP +\f[B]BclError bcl_pushContext(BclContext\f[R] \f[I]ctxt\f[R]**)** +.PP +: Pushes \f[I]ctxt\f[R] onto bcl(3)\[aq]s stack of contexts. \f[I]ctxt\f[R] must have been created with -\f[B]bcl_ctxt_create(\f[R]\f[I]void\f[R]\f[B])\f[R]. -.RS +\f[B]bcl_ctxt_create(\f[BI]\f[I]void\f[BI]\f[B])\f[R]. +.IP +.nf +\f[C] +If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this +function can return: + +* **BCL_ERROR_FATAL_ALLOC_ERR** + +There *must* be a valid context to do any arithmetic. +\f[R] +.fi .PP -If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned. -Otherwise, this function can return: -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] +\f[B]void bcl_popContext(\f[BI]\f[I]void\f[BI]\f[B])\f[R] .PP -There \f[I]must\f[R] be a valid context to do any arithmetic. -.RE -.TP -\f[B]void bcl_popContext(\f[R]\f[I]void\f[R]\f[B])\f[R] -Pops the current context off of the stack, if one exists. -.TP -\f[B]BclContext bcl_context(\f[R]\f[I]void\f[R]\f[B])\f[R] -Returns the current context, or \f[B]NULL\f[R] if no context exists. -.TP -\f[B]void bcl_ctxt_freeNums(BclContext\f[R] \f[I]ctxt\f[R]\f[B])\f[R] -Frees all numbers in use that are associated with \f[I]ctxt\f[R]. +: Pops the current context off of the stack, if one exists. +.PP +\f[B]BclContext bcl_context(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: Returns the current context, or \f[B]NULL\f[R] if no context exists. +.PP +\f[B]void bcl_ctxt_freeNums(BclContext\f[R] \f[I]ctxt\f[R]**)** +.PP +: Frees all numbers in use that are associated with \f[I]ctxt\f[R]. It is undefined behavior to attempt to use a number associated with \f[I]ctxt\f[R] after calling this procedure unless such numbers have -been created with \f[B]bcl_num_create(\f[R]\f[I]void\f[R]\f[B])\f[R] +been created with \f[B]bcl_num_create(\f[BI]\f[I]void\f[BI]\f[B])\f[R] after calling this procedure. -.TP -\f[B]size_t bcl_ctxt_scale(BclContext\f[R] \f[I]ctxt\f[R]\f[B])\f[R] -Returns the \f[B]scale\f[R] for given context. -.TP -\f[B]void bcl_ctxt_setScale(BclContext\f[R] \f[I]ctxt\f[R]\f[B], size_t\f[R] \f[I]scale\f[R]\f[B])\f[R] -Sets the \f[B]scale\f[R] for the given context to the argument +.PP +\f[B]size_t bcl_ctxt_scale(BclContext\f[R] \f[I]ctxt\f[R]**)** +.PP +: Returns the \f[B]scale\f[R] for given context. +.PP +\f[B]void bcl_ctxt_setScale(BclContext\f[R] \f[I]ctxt\f[R]**, size_t** +\f[I]scale\f[R]**)** +.PP +: Sets the \f[B]scale\f[R] for the given context to the argument \f[I]scale\f[R]. -.TP -\f[B]size_t bcl_ctxt_ibase(BclContext\f[R] \f[I]ctxt\f[R]\f[B])\f[R] -Returns the \f[B]ibase\f[R] for the given context. -.TP -\f[B]void bcl_ctxt_setIbase(BclContext\f[R] \f[I]ctxt\f[R]\f[B], size_t\f[R] \f[I]ibase\f[R]\f[B])\f[R] -Sets the \f[B]ibase\f[R] for the given context to the argument +.PP +\f[B]size_t bcl_ctxt_ibase(BclContext\f[R] \f[I]ctxt\f[R]**)** +.PP +: Returns the \f[B]ibase\f[R] for the given context. +.PP +\f[B]void bcl_ctxt_setIbase(BclContext\f[R] \f[I]ctxt\f[R]**, size_t** +\f[I]ibase\f[R]**)** +.PP +: Sets the \f[B]ibase\f[R] for the given context to the argument \f[I]ibase\f[R]. If the argument \f[I]ibase\f[R] is invalid, it clamped, so an \f[I]ibase\f[R] of \f[B]0\f[R] or \f[B]1\f[R] is clamped to \f[B]2\f[R], and any values above \f[B]36\f[R] are clamped to \f[B]36\f[R]. -.TP -\f[B]size_t bcl_ctxt_obase(BclContext\f[R] \f[I]ctxt\f[R]\f[B])\f[R] -Returns the \f[B]obase\f[R] for the given context. -.TP -\f[B]void bcl_ctxt_setObase(BclContext\f[R] \f[I]ctxt\f[R]\f[B], size_t\f[R] \f[I]obase\f[R]\f[B])\f[R] -Sets the \f[B]obase\f[R] for the given context to the argument +.PP +\f[B]size_t bcl_ctxt_obase(BclContext\f[R] \f[I]ctxt\f[R]**)** +.PP +: Returns the \f[B]obase\f[R] for the given context. +.PP +\f[B]void bcl_ctxt_setObase(BclContext\f[R] \f[I]ctxt\f[R]**, size_t** +\f[I]obase\f[R]**)** +.PP +: Sets the \f[B]obase\f[R] for the given context to the argument \f[I]obase\f[R]. .SS Errors -.TP +.PP \f[B]BclError\f[R] -An \f[B]enum\f[R] of possible error codes. +.PP +: An \f[B]enum\f[R] of possible error codes. See the \f[B]ERRORS\f[R] section for a complete listing the codes. -.TP -\f[B]BclError bcl_err(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R] -Checks for errors in a \f[B]BclNumber\f[R]. +.PP +\f[B]BclError bcl_err(BclNumber\f[R] \f[I]n\f[R]**)** +.PP +: Checks for errors in a \f[B]BclNumber\f[R]. All functions that can return a \f[B]BclNumber\f[R] can encode an error in the number, and this function will return the error, if any. If there was no error, it will return \f[B]BCL_ERROR_NONE\f[R]. -.RS -.PP +.IP +.nf +\f[C] There must be a valid current context. -.RE +\f[R] +.fi .SS Numbers .PP All procedures in this section require a valid current context. -.TP +.PP \f[B]BclNumber\f[R] -A handle to an arbitrary-precision number. +.PP +: A handle to an arbitrary-precision number. The actual number type is not exposed; the \f[B]BclNumber\f[R] handle is the only way clients can refer to instances of arbitrary-precision numbers. -.TP -\f[B]BclNumber bcl_num_create(\f[R]\f[I]void\f[R]\f[B])\f[R] -Creates and returns a \f[B]BclNumber\f[R]. -.RS .PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]void bcl_num_free(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R] -Frees \f[I]n\f[R]. +\f[B]BclNumber bcl_num_create(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: Creates and returns a \f[B]BclNumber\f[R]. +.IP +.nf +\f[C] +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi +.PP +\f[B]void bcl_num_free(BclNumber\f[R] \f[I]n\f[R]**)** +.PP +: Frees \f[I]n\f[R]. It is undefined behavior to use \f[I]n\f[R] after calling this function. -.TP -\f[B]bool bcl_num_neg(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R] -Returns \f[B]true\f[R] if \f[I]n\f[R] is negative, \f[B]false\f[R] -otherwise. -.TP -\f[B]void bcl_num_setNeg(BclNumber\f[R] \f[I]n\f[R]\f[B], bool\f[R] \f[I]neg\f[R]\f[B])\f[R] -Sets \f[I]n\f[R]\[cq]s sign to \f[I]neg\f[R], where \f[B]true\f[R] is -negative, and \f[B]false\f[R] is positive. -.TP -\f[B]size_t bcl_num_scale(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R] -Returns the \f[I]scale\f[R] of \f[I]n\f[R]. -.RS .PP -The \f[I]scale\f[R] of a number is the number of decimal places it has -after the radix (decimal point). -.RE -.TP -\f[B]BclError bcl_num_setScale(BclNumber\f[R] \f[I]n\f[R]\f[B], size_t\f[R] \f[I]scale\f[R]\f[B])\f[R] -Sets the \f[I]scale\f[R] of \f[I]n\f[R] to the argument \f[I]scale\f[R]. +\f[B]bool bcl_num_neg(BclNumber\f[R] \f[I]n\f[R]**)** +.PP +: Returns \f[B]true\f[R] if \f[I]n\f[R] is negative, \f[B]false\f[R] +otherwise. +.PP +\f[B]void bcl_num_setNeg(BclNumber\f[R] \f[I]n\f[R]**, bool** +\f[I]neg\f[R]**)** +.PP +: Sets \f[I]n\f[R]\[aq]s sign to \f[I]neg\f[R], where \f[B]true\f[R] is +negative, and \f[B]false\f[R] is positive. +.PP +\f[B]size_t bcl_num_scale(BclNumber\f[R] \f[I]n\f[R]**)** +.PP +: Returns the \f[I]scale\f[R] of \f[I]n\f[R]. +.IP +.nf +\f[C] +The *scale* of a number is the number of decimal places it has after the +radix (decimal point). +\f[R] +.fi +.PP +\f[B]BclError bcl_num_setScale(BclNumber\f[R] \f[I]n\f[R]**, size_t** +\f[I]scale\f[R]**)** +.PP +: Sets the \f[I]scale\f[R] of \f[I]n\f[R] to the argument +\f[I]scale\f[R]. If the argument \f[I]scale\f[R] is greater than the \f[I]scale\f[R] of \f[I]n\f[R], \f[I]n\f[R] is extended. If the argument \f[I]scale\f[R] is less than the \f[I]scale\f[R] of \f[I]n\f[R], \f[I]n\f[R] is truncated. -.RS +.IP +.nf +\f[C] +If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this +function can return: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned. -Otherwise, this function can return: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]size_t bcl_num_len(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R] -Returns the number of \f[I]significant decimal digits\f[R] in +\f[B]size_t bcl_num_len(BclNumber\f[R] \f[I]n\f[R]**)** +.PP +: Returns the number of \f[I]significant decimal digits\f[R] in \f[I]n\f[R]. .SS Conversion .PP @@ -508,72 +556,76 @@ All procedures in this section require a valid current context. All procedures in this section consume the given \f[B]BclNumber\f[R] arguments that are not given to pointer arguments. See the \f[B]Consumption and Propagation\f[R] subsection below. -.TP -\f[B]BclNumber bcl_parse(const char *restrict\f[R] \f[I]val\f[R]\f[B])\f[R] -Parses a number string according to the current context\[cq]s +.PP +\f[B]BclNumber bcl_parse(const char *restrict\f[R] \f[I]val\f[R]**)** +.PP +: Parses a number string according to the current context\[aq]s \f[B]ibase\f[R] and returns the resulting number. -.RS +.IP +.nf +\f[C] +*val* must be non-**NULL** and a valid string. See +**BCL_ERROR_PARSE_INVALID_STR** in the **ERRORS** section for more +information. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_PARSE_INVALID_STR** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]val\f[R] must be non-\f[B]NULL\f[R] and a valid string. -See \f[B]BCL_ERROR_PARSE_INVALID_STR\f[R] in the \f[B]ERRORS\f[R] -section for more information. +\f[B]char* bcl_string(BclNumber\f[R] \f[I]n\f[R]**)** .PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_PARSE_INVALID_STR\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]char* bcl_string(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R] -Returns a string representation of \f[I]n\f[R] according the the current -context\[cq]s \f[B]ibase\f[R]. +: Returns a string representation of \f[I]n\f[R] according the the +current context\[aq]s \f[B]ibase\f[R]. The string is dynamically allocated and must be freed by the caller. -.RS +.IP +.nf +\f[C] +*n* is consumed; it cannot be used after the call. See the +**Consumption and Propagation** subsection below. +\f[R] +.fi .PP -\f[I]n\f[R] is consumed; it cannot be used after the call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.RE -.TP -\f[B]BclError bcl_bigdig(BclNumber\f[R] \f[I]n\f[R]\f[B], BclBigDig *\f[R]\f[I]result\f[R]\f[B])\f[R] -Converts \f[I]n\f[R] into a \f[B]BclBigDig\f[R] and returns the result +\f[B]BclError bcl_bigdig(BclNumber\f[R] \f[I]n\f[R]**, BclBigDig +*\f[I]\f[BI]result\f[I]\f[R])** +.PP +: Converts \f[I]n\f[R] into a \f[B]BclBigDig\f[R] and returns the result in the space pointed to by \f[I]result\f[R]. -.RS +.IP +.nf +\f[C] +*a* must be smaller than **BC_OVERFLOW_MAX**. See the **LIMITS** section. + +If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this +function can return: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_OVERFLOW** + +*n* is consumed; it cannot be used after the call. See the +**Consumption and Propagation** subsection below. +\f[R] +.fi .PP -\f[I]a\f[R] must be smaller than \f[B]BC_OVERFLOW_MAX\f[R]. -See the \f[B]LIMITS\f[R] section. +\f[B]BclNumber bcl_bigdig2num(BclBigDig\f[R] \f[I]val\f[R]**)** .PP -If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned. -Otherwise, this function can return: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_OVERFLOW\f[R] -.PP -\f[I]n\f[R] is consumed; it cannot be used after the call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.RE -.TP -\f[B]BclNumber bcl_bigdig2num(BclBigDig\f[R] \f[I]val\f[R]\f[B])\f[R] -Creates a \f[B]BclNumber\f[R] from \f[I]val\f[R]. -.RS -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE +: Creates a \f[B]BclNumber\f[R] from \f[I]val\f[R]. +.IP +.nf +\f[C] +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .SS Math .PP All procedures in this section require a valid current context. @@ -585,352 +637,345 @@ All procedures in this section can return the following errors: \f[B]BCL_ERROR_INVALID_CONTEXT\f[R] .IP \[bu] 2 \f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.TP -\f[B]BclNumber bcl_add(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R] -Adds \f[I]a\f[R] and \f[I]b\f[R] and returns the result. +.PP +\f[B]BclNumber bcl_add(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**)** +.PP +: Adds \f[I]a\f[R] and \f[I]b\f[R] and returns the result. The \f[I]scale\f[R] of the result is the max of the \f[I]scale\f[R]s of \f[I]a\f[R] and \f[I]b\f[R]. -.RS +.IP +.nf +\f[C] +*a* and *b* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +*a* and *b* can be the same number. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]a\f[R] and \f[I]b\f[R] are consumed; they cannot be used after the -call. -See the \f[B]Consumption and Propagation\f[R] subsection below. +\f[B]BclNumber bcl_sub(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**)** .PP -\f[I]a\f[R] and \f[I]b\f[R] can be the same number. -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_sub(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R] -Subtracts \f[I]b\f[R] from \f[I]a\f[R] and returns the result. +: Subtracts \f[I]b\f[R] from \f[I]a\f[R] and returns the result. The \f[I]scale\f[R] of the result is the max of the \f[I]scale\f[R]s of \f[I]a\f[R] and \f[I]b\f[R]. -.RS +.IP +.nf +\f[C] +*a* and *b* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +*a* and *b* can be the same number. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]a\f[R] and \f[I]b\f[R] are consumed; they cannot be used after the -call. -See the \f[B]Consumption and Propagation\f[R] subsection below. +\f[B]BclNumber bcl_mul(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**)** .PP -\f[I]a\f[R] and \f[I]b\f[R] can be the same number. -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_mul(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R] -Multiplies \f[I]a\f[R] and \f[I]b\f[R] and returns the result. +: Multiplies \f[I]a\f[R] and \f[I]b\f[R] and returns the result. If \f[I]ascale\f[R] is the \f[I]scale\f[R] of \f[I]a\f[R] and \f[I]bscale\f[R] is the \f[I]scale\f[R] of \f[I]b\f[R], the \f[I]scale\f[R] of the result is equal to \f[B]min(ascale+bscale,max(scale,ascale,bscale))\f[R], where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.RS +.IP +.nf +\f[C] +*a* and *b* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +*a* and *b* can be the same number. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]a\f[R] and \f[I]b\f[R] are consumed; they cannot be used after the -call. -See the \f[B]Consumption and Propagation\f[R] subsection below. +\f[B]BclNumber bcl_div(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**)** .PP -\f[I]a\f[R] and \f[I]b\f[R] can be the same number. -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_div(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R] -Divides \f[I]a\f[R] by \f[I]b\f[R] and returns the result. +: Divides \f[I]a\f[R] by \f[I]b\f[R] and returns the result. The \f[I]scale\f[R] of the result is the \f[I]scale\f[R] of the current context. -.RS +.IP +.nf +\f[C] +*b* cannot be **0**. + +*a* and *b* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +*a* and *b* can be the same number. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_DIVIDE_BY_ZERO** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]b\f[R] cannot be \f[B]0\f[R]. +\f[B]BclNumber bcl_mod(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**)** .PP -\f[I]a\f[R] and \f[I]b\f[R] are consumed; they cannot be used after the -call. -See the \f[B]Consumption and Propagation\f[R] subsection below. +: Divides \f[I]a\f[R] by \f[I]b\f[R] to the \f[I]scale\f[R] of the +current context, computes the modulus \f[B]a-(a/b)*b\f[R], and returns +the modulus. +.IP +.nf +\f[C] +*b* cannot be **0**. + +*a* and *b* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +*a* and *b* can be the same number. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_DIVIDE_BY_ZERO** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]a\f[R] and \f[I]b\f[R] can be the same number. +\f[B]BclNumber bcl_pow(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**)** .PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_mod(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R] -Divides \f[I]a\f[R] by \f[I]b\f[R] to the \f[I]scale\f[R] of the current -context, computes the modulus \f[B]a-(a/b)*b\f[R], and returns the -modulus. -.RS -.PP -\f[I]b\f[R] cannot be \f[B]0\f[R]. -.PP -\f[I]a\f[R] and \f[I]b\f[R] are consumed; they cannot be used after the -call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.PP -\f[I]a\f[R] and \f[I]b\f[R] can be the same number. -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_pow(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R] -Calculates \f[I]a\f[R] to the power of \f[I]b\f[R] to the +: Calculates \f[I]a\f[R] to the power of \f[I]b\f[R] to the \f[I]scale\f[R] of the current context. \f[I]b\f[R] must be an integer, but can be negative. If it is negative, \f[I]a\f[R] must be non-zero. -.RS +.IP +.nf +\f[C] +*b* must be an integer. If *b* is negative, *a* must not be **0**. + +*a* must be smaller than **BC_OVERFLOW_MAX**. See the **LIMITS** section. + +*a* and *b* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +*a* and *b* can be the same number. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_NON_INTEGER** +* **BCL_ERROR_MATH_OVERFLOW** +* **BCL_ERROR_MATH_DIVIDE_BY_ZERO** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]b\f[R] must be an integer. -If \f[I]b\f[R] is negative, \f[I]a\f[R] must not be \f[B]0\f[R]. +\f[B]BclNumber bcl_lshift(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**)** .PP -\f[I]a\f[R] must be smaller than \f[B]BC_OVERFLOW_MAX\f[R]. -See the \f[B]LIMITS\f[R] section. -.PP -\f[I]a\f[R] and \f[I]b\f[R] are consumed; they cannot be used after the -call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.PP -\f[I]a\f[R] and \f[I]b\f[R] can be the same number. -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_OVERFLOW\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_lshift(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R] -Shifts \f[I]a\f[R] left (moves the radix right) by \f[I]b\f[R] places +: Shifts \f[I]a\f[R] left (moves the radix right) by \f[I]b\f[R] places and returns the result. This is done in decimal. \f[I]b\f[R] must be an integer. -.RS +.IP +.nf +\f[C] +*b* must be an integer. + +*a* and *b* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +*a* and *b* can be the same number. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_NON_INTEGER** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]b\f[R] must be an integer. +\f[B]BclNumber bcl_rshift(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**)** .PP -\f[I]a\f[R] and \f[I]b\f[R] are consumed; they cannot be used after the -call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.PP -\f[I]a\f[R] and \f[I]b\f[R] can be the same number. -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_rshift(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R] -Shifts \f[I]a\f[R] right (moves the radix left) by \f[I]b\f[R] places +: Shifts \f[I]a\f[R] right (moves the radix left) by \f[I]b\f[R] places and returns the result. This is done in decimal. \f[I]b\f[R] must be an integer. -.RS +.IP +.nf +\f[C] +*b* must be an integer. + +*a* and *b* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +*a* and *b* can be the same number. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_NON_INTEGER** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]b\f[R] must be an integer. +\f[B]BclNumber bcl_sqrt(BclNumber\f[R] \f[I]a\f[R]**)** .PP -\f[I]a\f[R] and \f[I]b\f[R] are consumed; they cannot be used after the -call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.PP -\f[I]a\f[R] and \f[I]b\f[R] can be the same number. -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_sqrt(BclNumber\f[R] \f[I]a\f[R]\f[B])\f[R] -Calculates the square root of \f[I]a\f[R] and returns the result. +: Calculates the square root of \f[I]a\f[R] and returns the result. The \f[I]scale\f[R] of the result is equal to the \f[B]scale\f[R] of the current context. -.RS +.IP +.nf +\f[C] +*a* cannot be negative. + +*a* is consumed; it cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_NEGATIVE** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]a\f[R] cannot be negative. +\f[B]BclError bcl_divmod(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**, BclNumber *\f[I]\f[BI]c\f[I]\f[R], BclNumber +*\f[I]\f[BI]d\f[I]\f[R])** .PP -\f[I]a\f[R] is consumed; it cannot be used after the call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NEGATIVE\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclError bcl_divmod(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber *\f[R]\f[I]c\f[R]\f[B], BclNumber *\f[R]\f[I]d\f[R]\f[B])\f[R] -Divides \f[I]a\f[R] by \f[I]b\f[R] and returns the quotient in a new +: Divides \f[I]a\f[R] by \f[I]b\f[R] and returns the quotient in a new number which is put into the space pointed to by \f[I]c\f[R], and puts the modulus in a new number which is put into the space pointed to by \f[I]d\f[R]. -.RS +.IP +.nf +\f[C] +*b* cannot be **0**. + +*a* and *b* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +*c* and *d* cannot point to the same place, nor can they point to the space +occupied by *a* or *b*. + +If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this +function can return: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_DIVIDE_BY_ZERO** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -\f[I]b\f[R] cannot be \f[B]0\f[R]. +\f[B]BclNumber bcl_modexp(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**, BclNumber** \f[I]c\f[R]**)** .PP -\f[I]a\f[R] and \f[I]b\f[R] are consumed; they cannot be used after the -call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.PP -\f[I]c\f[R] and \f[I]d\f[R] cannot point to the same place, nor can they -point to the space occupied by \f[I]a\f[R] or \f[I]b\f[R]. -.PP -If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned. -Otherwise, this function can return: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_modexp(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B], BclNumber\f[R] \f[I]c\f[R]\f[B])\f[R] -Computes a modular exponentiation where \f[I]a\f[R] is the base, +: Computes a modular exponentiation where \f[I]a\f[R] is the base, \f[I]b\f[R] is the exponent, and \f[I]c\f[R] is the modulus, and returns the result. The \f[I]scale\f[R] of the result is equal to the \f[B]scale\f[R] of the current context. -.RS -.PP -\f[I]a\f[R], \f[I]b\f[R], and \f[I]c\f[R] must be integers. -\f[I]c\f[R] must not be \f[B]0\f[R]. -\f[I]b\f[R] must not be negative. -.PP -\f[I]a\f[R], \f[I]b\f[R], and \f[I]c\f[R] are consumed; they cannot be -used after the call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NEGATIVE\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE +.IP +.nf +\f[C] +*a*, *b*, and *c* must be integers. *c* must not be **0**. *b* must not be +negative. + +*a*, *b*, and *c* are consumed; they cannot be used after the call. See the +**Consumption and Propagation** subsection below. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_NEGATIVE** +* **BCL_ERROR_MATH_NON_INTEGER** +* **BCL_ERROR_MATH_DIVIDE_BY_ZERO** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .SS Miscellaneous -.TP -\f[B]void bcl_zero(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R] -Sets \f[I]n\f[R] to \f[B]0\f[R]. -.TP -\f[B]void bcl_one(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R] -Sets \f[I]n\f[R] to \f[B]1\f[R]. -.TP -\f[B]ssize_t bcl_cmp(BclNumber\f[R] \f[I]a\f[R]\f[B], BclNumber\f[R] \f[I]b\f[R]\f[B])\f[R] -Compares \f[I]a\f[R] and \f[I]b\f[R] and returns \f[B]0\f[R] if +.PP +\f[B]void bcl_zero(BclNumber\f[R] \f[I]n\f[R]**)** +.PP +: Sets \f[I]n\f[R] to \f[B]0\f[R]. +.PP +\f[B]void bcl_one(BclNumber\f[R] \f[I]n\f[R]**)** +.PP +: Sets \f[I]n\f[R] to \f[B]1\f[R]. +.PP +\f[B]ssize_t bcl_cmp(BclNumber\f[R] \f[I]a\f[R]**, BclNumber** +\f[I]b\f[R]**)** +.PP +: Compares \f[I]a\f[R] and \f[I]b\f[R] and returns \f[B]0\f[R] if \f[I]a\f[R] and \f[I]b\f[R] are equal, \f[B]<0\f[R] if \f[I]a\f[R] is less than \f[I]b\f[R], and \f[B]>0\f[R] if \f[I]a\f[R] is greater than \f[I]b\f[R]. -.TP -\f[B]BclError bcl_copy(BclNumber\f[R] \f[I]d\f[R]\f[B], BclNumber\f[R] \f[I]s\f[R]\f[B])\f[R] -Copies \f[I]s\f[R] into \f[I]d\f[R]. -.RS .PP -If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned. -Otherwise, this function can return: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_dup(BclNumber\f[R] \f[I]s\f[R]\f[B])\f[R] -Creates and returns a new \f[B]BclNumber\f[R] that is a copy of +\f[B]BclError bcl_copy(BclNumber\f[R] \f[I]d\f[R]**, BclNumber** +\f[I]s\f[R]**)** +.PP +: Copies \f[I]s\f[R] into \f[I]d\f[R]. +.IP +.nf +\f[C] +If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this +function can return: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi +.PP +\f[B]BclNumber bcl_dup(BclNumber\f[R] \f[I]s\f[R]**)** +.PP +: Creates and returns a new \f[B]BclNumber\f[R] that is a copy of \f[I]s\f[R]. -.RS -.PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE +.IP +.nf +\f[C] +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .SS Pseudo-Random Number Generator .PP The pseudo-random number generator in bcl(3) is a \f[I]seeded\f[R] PRNG. @@ -939,7 +984,7 @@ pseudo-random numbers twice. .PP By default, bcl(3) attempts to seed the PRNG with data from \f[B]/dev/urandom\f[R]. -If that fails, it seeds itself with by calling \f[B]libc\f[R]\[cq]s +If that fails, it seeds itself with by calling \f[B]libc\f[R]\[aq]s \f[B]srand(time(NULL))\f[R] and then calling \f[B]rand()\f[R] for each byte, since \f[B]rand()\f[R] is only guaranteed to return \f[B]15\f[R] bits. @@ -954,29 +999,34 @@ functions: .IP \[bu] 2 \f[B]bcl_rand_seed(unsigned char[BC_SEED_SIZE])\f[R] .IP \[bu] 2 -\f[B]bcl_rand_reseed(\f[R]\f[I]void\f[R]\f[B])\f[R] +\f[B]bcl_rand_reseed(\f[BI]\f[I]void\f[BI]\f[B])\f[R] .PP The following items allow clients to use the pseudo-random number generator. All procedures require a valid current context. -.TP +.PP \f[B]BCL_SEED_ULONGS\f[R] -The number of \f[B]unsigned long\f[R]\[cq]s in a seed for bcl(3)\[cq]s +.PP +: The number of \f[B]unsigned long\f[R]\[aq]s in a seed for bcl(3)\[aq]s random number generator. -.TP +.PP \f[B]BCL_SEED_SIZE\f[R] -The size, in \f[B]char\f[R]\[cq]s, of a seed for bcl(3)\[cq]s random +.PP +: The size, in \f[B]char\f[R]\[aq]s, of a seed for bcl(3)\[aq]s random number generator. -.TP +.PP \f[B]BclBigDig\f[R] -bcl(3)\[cq]s overflow type (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP +: bcl(3)\[aq]s overflow type (see the \f[B]PERFORMANCE\f[R] section). +.PP \f[B]BclRandInt\f[R] -An unsigned integer type returned by bcl(3)\[cq]s random number +.PP +: An unsigned integer type returned by bcl(3)\[aq]s random number generator. -.TP -\f[B]BclNumber bcl_irand(BclNumber\f[R] \f[I]a\f[R]\f[B])\f[R] -Returns a random number that is not larger than \f[I]a\f[R] in a new +.PP +\f[B]BclNumber bcl_irand(BclNumber\f[R] \f[I]a\f[R]**)** +.PP +: Returns a random number that is not larger than \f[I]a\f[R] in a new number. If \f[I]a\f[R] is \f[B]0\f[R] or \f[B]1\f[R], the new number is equal to \f[B]0\f[R]. @@ -984,147 +1034,159 @@ The bound is unlimited, so it is not bound to the size of \f[B]BclRandInt\f[R]. This is done by generating as many random numbers as necessary, multiplying them by certain exponents, and adding them all together. -.RS -.PP -\f[I]a\f[R] must be an integer and non-negative. -.PP -\f[I]a\f[R] is consumed; it cannot be used after the call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.PP +.IP +.nf +\f[C] +*a* must be an integer and non-negative. + +*a* is consumed; it cannot be used after the call. See the +**Consumption and Propagation** subsection below. + This procedure requires a valid current context. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_NEGATIVE** +* **BCL_ERROR_MATH_NON_INTEGER** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NEGATIVE\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_frand(size_t\f[R] \f[I]places\f[R]\f[B])\f[R] -Returns a random number between \f[B]0\f[R] (inclusive) and \f[B]1\f[R] -(exclusive) that has \f[I]places\f[R] decimal digits after the radix -(decimal point). +\f[B]BclNumber bcl_frand(size_t\f[R] \f[I]places\f[R]**)** +.PP +: Returns a random number between \f[B]0\f[R] (inclusive) and +\f[B]1\f[R] (exclusive) that has \f[I]places\f[R] decimal digits after +the radix (decimal point). There are no limits on \f[I]places\f[R]. -.RS -.PP +.IP +.nf +\f[C] This procedure requires a valid current context. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclNumber bcl_ifrand(BclNumber\f[R] \f[I]a\f[R]\f[B], size_t\f[R] \f[I]places\f[R]\f[B])\f[R] -Returns a random number less than \f[I]a\f[R] with \f[I]places\f[R] +\f[B]BclNumber bcl_ifrand(BclNumber\f[R] \f[I]a\f[R]**, size_t** +\f[I]places\f[R]**)** +.PP +: Returns a random number less than \f[I]a\f[R] with \f[I]places\f[R] decimal digits after the radix (decimal point). There are no limits on \f[I]a\f[R] or \f[I]places\f[R]. -.RS -.PP -\f[I]a\f[R] must be an integer and non-negative. -.PP -\f[I]a\f[R] is consumed; it cannot be used after the call. -See the \f[B]Consumption and Propagation\f[R] subsection below. -.PP +.IP +.nf +\f[C] +*a* must be an integer and non-negative. + +*a* is consumed; it cannot be used after the call. See the +**Consumption and Propagation** subsection below. + This procedure requires a valid current context. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_MATH_NEGATIVE** +* **BCL_ERROR_MATH_NON_INTEGER** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NEGATIVE\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_MATH_NON_INTEGER\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclError bcl_rand_seedWithNum(BclNumber\f[R] \f[I]n\f[R]\f[B])\f[R] -Seeds the PRNG with \f[I]n\f[R]. -.RS -.PP -\f[I]n\f[R] is \f[I]not\f[R] consumed. +\f[B]BclError bcl_rand_seedWithNum(BclNumber\f[R] \f[I]n\f[R]**)** .PP +: Seeds the PRNG with \f[I]n\f[R]. +.IP +.nf +\f[C] +*n* is *not* consumed. + This procedure requires a valid current context. + +If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this +function can return: + +* **BCL_ERROR_INVALID_NUM** +* **BCL_ERROR_INVALID_CONTEXT** + +Note that if **bcl_rand_seed2num(***void***)** or +**bcl_rand_seed2num_err(BclNumber)** are called right after this function, +they are not guaranteed to return a number equal to *n*. +\f[R] +.fi .PP -If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned. -Otherwise, this function can return: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_NUM\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] +\f[B]BclError bcl_rand_seed(unsigned char\f[R] +\f[I]seed\f[R]**[\f[I]\f[BI]BC_SEED_SIZE\f[I]\f[R]])** .PP -Note that if \f[B]bcl_rand_seed2num(\f[R]\f[I]void\f[R]\f[B])\f[R] or -\f[B]bcl_rand_seed2num_err(BclNumber)\f[R] are called right after this -function, they are not guaranteed to return a number equal to -\f[I]n\f[R]. -.RE -.TP -\f[B]BclError bcl_rand_seed(unsigned char\f[R] \f[I]seed\f[R]\f[B][\f[R]\f[I]BC_SEED_SIZE\f[R]\f[B]])\f[R] -Seeds the PRNG with the bytes in \f[I]seed\f[R]. -.RS +: Seeds the PRNG with the bytes in \f[I]seed\f[R]. +.IP +.nf +\f[C] +If there was no error, **BCL_ERROR_NONE** is returned. Otherwise, this +function can return: + +* **BCL_ERROR_INVALID_CONTEXT** +\f[R] +.fi .PP -If there was no error, \f[B]BCL_ERROR_NONE\f[R] is returned. -Otherwise, this function can return: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.RE -.TP -\f[B]void bcl_rand_reseed(\f[R]\f[I]void\f[R]\f[B])\f[R] -Reseeds the PRNG with the default reseeding behavior. +\f[B]void bcl_rand_reseed(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: Reseeds the PRNG with the default reseeding behavior. First, it attempts to read data from \f[B]/dev/urandom\f[R] and falls -back to \f[B]libc\f[R]\[cq]s \f[B]rand()\f[R]. -.RS -.PP +back to \f[B]libc\f[R]\[aq]s \f[B]rand()\f[R]. +.IP +.nf +\f[C] This procedure cannot fail. -.RE -.TP -\f[B]BclNumber bcl_rand_seed2num(\f[R]\f[I]void\f[R]\f[B])\f[R] -Returns the current seed of the PRNG as a \f[B]BclNumber\f[R]. -.RS +\f[R] +.fi .PP +\f[B]BclNumber bcl_rand_seed2num(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: Returns the current seed of the PRNG as a \f[B]BclNumber\f[R]. +.IP +.nf +\f[C] This procedure requires a valid current context. + +bcl(3) will encode an error in the return value, if there was one. The error +can be queried with **bcl_err(BclNumber)**. Possible errors include: + +* **BCL_ERROR_INVALID_CONTEXT** +* **BCL_ERROR_FATAL_ALLOC_ERR** +\f[R] +.fi .PP -bcl(3) will encode an error in the return value, if there was one. -The error can be queried with \f[B]bcl_err(BclNumber)\f[R]. -Possible errors include: -.IP \[bu] 2 -\f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -.IP \[bu] 2 -\f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -.RE -.TP -\f[B]BclRandInt bcl_rand_int(\f[R]\f[I]void\f[R]\f[B])\f[R] -Returns a random integer between \f[B]0\f[R] and \f[B]BC_RAND_MAX\f[R] +\f[B]BclRandInt bcl_rand_int(\f[BI]\f[I]void\f[BI]\f[B])\f[R] +.PP +: Returns a random integer between \f[B]0\f[R] and \f[B]BC_RAND_MAX\f[R] (inclusive). -.RS -.PP +.IP +.nf +\f[C] This procedure cannot fail. -.RE -.TP -\f[B]BclRandInt bcl_rand_bounded(BclRandInt\f[R] \f[I]bound\f[R]\f[B])\f[R] -Returns a random integer between \f[B]0\f[R] and \f[I]bound\f[R] +\f[R] +.fi +.PP +\f[B]BclRandInt bcl_rand_bounded(BclRandInt\f[R] \f[I]bound\f[R]**)** +.PP +: Returns a random integer between \f[B]0\f[R] and \f[I]bound\f[R] (exclusive). Bias is removed before returning the integer. -.RS -.PP +.IP +.nf +\f[C] This procedure cannot fail. -.RE +\f[R] +.fi .SS Consumption and Propagation .PP Some functions are listed as consuming some or all of their arguments. @@ -1159,95 +1221,105 @@ if (bc_num_err(n) != BCL_ERROR_NONE) { Most functions in bcl(3) return, directly or indirectly, any one of the error codes defined in \f[B]BclError\f[R]. The complete list of codes is the following: -.TP +.PP \f[B]BCL_ERROR_NONE\f[R] -Success; no error occurred. -.TP +.PP +: Success; no error occurred. +.PP \f[B]BCL_ERROR_INVALID_NUM\f[R] -An invalid \f[B]BclNumber\f[R] was given as a parameter. -.TP +.PP +: An invalid \f[B]BclNumber\f[R] was given as a parameter. +.PP \f[B]BCL_ERROR_INVALID_CONTEXT\f[R] -An invalid \f[B]BclContext\f[R] is being used. -.TP +.PP +: An invalid \f[B]BclContext\f[R] is being used. +.PP \f[B]BCL_ERROR_SIGNAL\f[R] -A signal interrupted execution. -.TP +.PP +: A signal interrupted execution. +.PP \f[B]BCL_ERROR_MATH_NEGATIVE\f[R] -A negative number was given as an argument to a parameter that cannot +.PP +: A negative number was given as an argument to a parameter that cannot accept negative numbers, such as for square roots. -.TP +.PP \f[B]BCL_ERROR_MATH_NON_INTEGER\f[R] -A non-integer was given as an argument to a parameter that cannot accept -non-integer numbers, such as for the second parameter of +.PP +: A non-integer was given as an argument to a parameter that cannot +accept non-integer numbers, such as for the second parameter of \f[B]bcl_num_pow()\f[R]. -.TP +.PP \f[B]BCL_ERROR_MATH_OVERFLOW\f[R] -A number that would overflow its result was given as an argument, such +.PP +: A number that would overflow its result was given as an argument, such as for converting a \f[B]BclNumber\f[R] to a \f[B]BclBigDig\f[R]. -.TP +.PP \f[B]BCL_ERROR_MATH_DIVIDE_BY_ZERO\f[R] -A divide by zero occurred. -.TP +.PP +: A divide by zero occurred. +.PP \f[B]BCL_ERROR_PARSE_INVALID_STR\f[R] -An invalid number string was passed to a parsing function. -.RS .PP -A valid number string can only be one radix (period). -In addition, any lowercase ASCII letters, symbols, or non-ASCII -characters are invalid. -It is allowed for the first character to be a dash. -In that case, the number is considered to be negative. -.PP -There is one exception to the above: one lowercase \f[B]e\f[R] is -allowed in the number, after the radix, if it exists. -If the letter \f[B]e\f[R] exists, the number is considered to be in -scientific notation, where the part before the \f[B]e\f[R] is the -number, and the part after, which must be an integer, is the exponent. -There can be a dash right after the \f[B]e\f[R] to indicate a negative +: An invalid number string was passed to a parsing function. +.IP +.nf +\f[C] +A valid number string can only be one radix (period). In addition, any +lowercase ASCII letters, symbols, or non-ASCII characters are invalid. It is +allowed for the first character to be a dash. In that case, the number is +considered to be negative. + +There is one exception to the above: one lowercase **e** is allowed in the +number, after the radix, if it exists. If the letter **e** exists, the +number is considered to be in scientific notation, where the part before the +**e** is the number, and the part after, which must be an integer, is the +exponent. There can be a dash right after the **e** to indicate a negative exponent. + +**WARNING**: Both the number and the exponent in scientific notation are +interpreted according to the current **ibase**, but the number is still +multiplied by **10\[rs]\[ha]exponent** regardless of the current **ibase**. For +example, if **ibase** is **16** and bcl(3) is given the number string +**FFeA**, the resulting decimal number will be **2550000000000**, and if +bcl(3) is given the number string **10e-4**, the resulting decimal number +will be **0.0016**. +\f[R] +.fi .PP -\f[B]WARNING\f[R]: Both the number and the exponent in scientific -notation are interpreted according to the current \f[B]ibase\f[R], but -the number is still multiplied by \f[B]10\[ha]exponent\f[R] regardless -of the current \f[B]ibase\f[R]. -For example, if \f[B]ibase\f[R] is \f[B]16\f[R] and bcl(3) is given the -number string \f[B]FFeA\f[R], the resulting decimal number will be -\f[B]2550000000000\f[R], and if bcl(3) is given the number string -\f[B]10e-4\f[R], the resulting decimal number will be \f[B]0.0016\f[R]. -.RE -.TP \f[B]BCL_ERROR_FATAL_ALLOC_ERR\f[R] -bcl(3) failed to allocate memory. -.RS .PP -If clients call \f[B]bcl_setAbortOnFatalError()\f[R] with an -\f[B]true\f[R] argument, this error will cause bcl(3) to throw a -\f[B]SIGABRT\f[R]. -This behavior can also be turned off later by calling that same function -with a \f[B]false\f[R] argument. +: bcl(3) failed to allocate memory. +.IP +.nf +\f[C] +If clients call **bcl_setAbortOnFatalError()** with an **true** argument, +this error will cause bcl(3) to throw a **SIGABRT**. This behavior can also +be turned off later by calling that same function with a **false** argument. By default, this behavior is off. + +It is highly recommended that client libraries do *not* activate this +behavior. +\f[R] +.fi .PP -It is highly recommended that client libraries do \f[I]not\f[R] activate -this behavior. -.RE -.TP \f[B]BCL_ERROR_FATAL_UNKNOWN_ERR\f[R] -An unknown error occurred. -.RS .PP -If clients call \f[B]bcl_setAbortOnFatalError()\f[R] with an -\f[B]true\f[R] argument, this error will cause bcl(3) to throw a -\f[B]SIGABRT\f[R]. -This behavior can also be turned off later by calling that same function -with a \f[B]false\f[R] argument. +: An unknown error occurred. +.IP +.nf +\f[C] +If clients call **bcl_setAbortOnFatalError()** with an **true** argument, +this error will cause bcl(3) to throw a **SIGABRT**. This behavior can also +be turned off later by calling that same function with a **false** argument. By default, this behavior is off. -.PP -It is highly recommended that client libraries do \f[I]not\f[R] activate -this behavior. -.RE + +It is highly recommended that client libraries do *not* activate this +behavior. +\f[R] +.fi .SH ATTRIBUTES .PP -When \f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] is used +When \f[B]bcl_handleSignal(\f[BI]\f[I]void\f[BI]\f[B])\f[R] is used properly, bcl(3) is async-signal-safe. .PP bcl(3) is \f[I]MT-Unsafe\f[R]: it is unsafe to call any functions from @@ -1275,48 +1347,57 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on bcl(3): -.TP +.PP \f[B]BC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where bcl(3) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]BC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]BC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]BC_BASE_DIGS\f[R]. -.TP +.PP \f[B]BC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]BC_LONG_BIT\f[R]. -.TP +.PP \f[B]BC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]BC_BASE_POW\f[R]. -.TP +.PP \f[B]BC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]BC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]BC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]bcl_rand_int()\f[R] -function. +.PP +: The maximum integer (inclusive) returned by the +\f[B]bcl_rand_int()\f[R] function. Set at \f[B]2\[ha]BC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]BC_OVERFLOW_MAX\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -1326,7 +1407,7 @@ In fact, memory should be exhausted before these limits should be hit. .SH SIGNAL HANDLING .PP If a signal handler calls -\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] from the same +\f[B]bcl_handleSignal(\f[BI]\f[I]void\f[BI]\f[B])\f[R] from the same thread that there are bcl(3) functions executing in, it will cause all execution to stop as soon as possible, interrupting long-running calculations, if necessary and cause the function that was executing to @@ -1334,11 +1415,11 @@ return. If possible, the error code \f[B]BC_ERROR_SIGNAL\f[R] is returned. .PP If execution \f[I]is\f[R] interrupted, -\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] does \f[I]not\f[R] -return to its caller. +\f[B]bcl_handleSignal(\f[BI]\f[I]void\f[BI]\f[B])\f[R] does +\f[I]not\f[R] return to its caller. .PP It is undefined behavior if -\f[B]bcl_handleSignal(\f[R]\f[I]void\f[R]\f[B])\f[R] is called from a +\f[B]bcl_handleSignal(\f[BI]\f[I]void\f[BI]\f[B])\f[R] is called from a thread that is not executing bcl(3) functions, if bcl(3) functions are executing. .SH SEE ALSO diff --git a/manuals/build.md b/manuals/build.md index a58da6d427ed..656aa5250739 100644 --- a/manuals/build.md +++ b/manuals/build.md @@ -37,9 +37,50 @@ See [Build Environment Variables][4] for a more detailed description of all accepted environment variables and [Build Options][5] for more detail about all accepted build options. +## Windows + +On Windows, this `bc` can be built using Visual Studio or MSBuild. + +However, only one build configuration (besides Debug or Release) is supported: +extra math and prompt enabled, history and NLS (locale support) disabled, with +both calculators built. + +The library can also be built on Windows. + +### Visual Studio + +In Visual Studio, open up the solution file (`bc.sln` for `bc`, or `bcl.sln` for +the library), select the desired configuration, and build. + +### MSBuild + +To build with MSBuild, first, *be sure that you are using the MSBuild that comes +with Visual Studio*. + +To build `bc`, run the following from the root directory: + +``` +msbuild -property:Configuration= bc.sln +``` + +where `` is either one of `Debug` or `Release`. + +To build the library, run the following from the root directory: + +``` +msbuild -property:Configuration= bcl.sln +``` + +where `` is either one of `Debug` or `Release`. + +## POSIX-Compatible Systems + +Building `bc`, `dc`, and `bcl` (the library) is more complex than on Windows +because many build options are supported. + -## Cross Compiling +### Cross Compiling To cross-compile this `bc`, an appropriate compiler must be present and assigned to the environment variable `HOSTCC` or `HOST_CC` (the two are equivalent, @@ -69,7 +110,7 @@ the environment variable `GEN_EMU`. -## Build Environment Variables +### Build Environment Variables This `bc` supports `CC`, `HOSTCC`, `HOST_CC`, `CFLAGS`, `HOSTCFLAGS`, `HOST_CFLAGS`, `CPPFLAGS`, `LDFLAGS`, `LDLIBS`, `PREFIX`, `DESTDIR`, `BINDIR`, @@ -81,7 +122,7 @@ put into the generated Makefile. More detail on what those environment variables do can be found in the following sections. -### `CC` +#### `CC` C compiler for the target system. `CC` must be compatible with POSIX `c99` behavior and options. However, **I encourage users to use any C99 or C11 @@ -104,33 +145,33 @@ automatically moved into HOSTCFLAGS. Defaults to `$CC`. -### `CFLAGS` +#### `CFLAGS` Command-line flags that will be passed verbatim to `CC`. Defaults to empty. -### `HOSTCFLAGS` or `HOST_CFLAGS` +#### `HOSTCFLAGS` or `HOST_CFLAGS` Command-line flags that will be passed verbatim to `HOSTCC` or `HOST_CC`. Defaults to `$CFLAGS`. -### `CPPFLAGS` +#### `CPPFLAGS` Command-line flags for the C preprocessor. These are also passed verbatim to both compilers (`CC` and `HOSTCC`); they are supported just for legacy reasons. Defaults to empty. -### `LDFLAGS` +#### `LDFLAGS` Command-line flags for the linker. These are also passed verbatim to both compilers (`CC` and `HOSTCC`); they are supported just for legacy reasons. Defaults to empty. -### `LDLIBS` +#### `LDLIBS` Libraries to link to. These are also passed verbatim to both compilers (`CC` and `HOSTCC`); they are supported just for legacy reasons and for cross compiling @@ -138,7 +179,7 @@ with different C standard libraries (like [musl][3]). Defaults to empty. -### `PREFIX` +#### `PREFIX` The prefix to install to. @@ -146,7 +187,7 @@ Can be overridden by passing the `--prefix` option to `configure.sh`. Defaults to `/usr/local`. -### `DESTDIR` +#### `DESTDIR` Path to prepend onto `PREFIX`. This is mostly for distro and package maintainers. @@ -156,7 +197,7 @@ to both, the one given to `configure.sh` takes precedence. Defaults to empty. -### `BINDIR` +#### `BINDIR` The directory to install binaries in. @@ -164,7 +205,7 @@ Can be overridden by passing the `--bindir` option to `configure.sh`. Defaults to `$PREFIX/bin`. -### `INCLUDEDIR` +#### `INCLUDEDIR` The directory to install header files in. @@ -172,7 +213,7 @@ Can be overridden by passing the `--includedir` option to `configure.sh`. Defaults to `$PREFIX/include`. -### `LIBDIR` +#### `LIBDIR` The directory to install libraries in. @@ -180,7 +221,7 @@ Can be overridden by passing the `--libdir` option to `configure.sh`. Defaults to `$PREFIX/lib`. -### `DATAROOTDIR` +#### `DATAROOTDIR` The root directory to install data files in. @@ -188,7 +229,7 @@ Can be overridden by passing the `--datarootdir` option to `configure.sh`. Defaults to `$PREFIX/share`. -### `DATADIR` +#### `DATADIR` The directory to install data files in. @@ -196,7 +237,7 @@ Can be overridden by passing the `--datadir` option to `configure.sh`. Defaults to `$DATAROOTDIR`. -### `MANDIR` +#### `MANDIR` The directory to install manpages in. @@ -204,7 +245,7 @@ Can be overridden by passing the `--mandir` option to `configure.sh`. Defaults to `$DATADIR/man` -### `MAN1DIR` +#### `MAN1DIR` The directory to install Section 1 manpages in. Because both `bc` and `dc` are Section 1 commands, this is the only relevant section directory. @@ -213,7 +254,7 @@ Can be overridden by passing the `--man1dir` option to `configure.sh`. Defaults to `$MANDIR/man1`. -### `LOCALEDIR` +#### `LOCALEDIR` The directory to install locales in. @@ -221,7 +262,7 @@ Can be overridden by passing the `--localedir` option to `configure.sh`. Defaults to `$DATAROOTDIR/locale`. -### `EXECSUFFIX` +#### `EXECSUFFIX` The suffix to append onto the executable names *when installing*. This is for packagers and distro maintainers who want this `bc` as an option, but do not @@ -229,7 +270,7 @@ want to replace the default `bc`. Defaults to empty. -### `EXECPREFIX` +#### `EXECPREFIX` The prefix to append onto the executable names *when building and installing*. This is for packagers and distro maintainers who want this `bc` as an option, @@ -237,7 +278,7 @@ but do not want to replace the default `bc`. Defaults to empty. -### `LONG_BIT` +#### `LONG_BIT` The number of bits in a C `long` type. This is mostly for the embedded space. @@ -254,7 +295,7 @@ compliance with the `bc` spec, the minimum allowed value is `32`. It is an error if the specified value is greater than the default value of `LONG_BIT` for the target platform. -### `GEN_HOST` +#### `GEN_HOST` Whether to use `gen/strgen.c`, instead of `gen/strgen.sh`, to produce the C files that contain the help texts as well as the math libraries. By default, @@ -274,7 +315,7 @@ or a non-existent value, will cause the build system to compile and run Default is "". -### `GEN_EMU` +#### `GEN_EMU` The emulator to run bootstrap binaries under. This is only if the binaries produced by `HOSTCC` (or `HOST_CC`) need to be run under an emulator to work. @@ -283,7 +324,7 @@ Defaults to empty. -## Build Options +### Build Options This `bc` comes with several build options, all of which are enabled by default. @@ -298,7 +339,7 @@ following forms: --option=arg ``` -### Library +#### Library To build the math library, use the following commands for the configure step: @@ -321,7 +362,7 @@ is installed. The library is built as `bin/libbcl.a`. -### `bc` Only +#### `bc` Only To build `bc` only (no `dc`), use any one of the following commands for the configure step: @@ -338,7 +379,7 @@ Those commands are all equivalent. ***Warning***: It is an error to use those options if `bc` has also been disabled (see below). -### `dc` Only +#### `dc` Only To build `dc` only (no `bc`), use either one of the following commands for the configure step: @@ -357,7 +398,7 @@ disabled (see above). -### History +#### History To disable signal handling, pass either the `-H` flag or the `--disable-history` option to `configure.sh`, as follows: @@ -376,7 +417,7 @@ platform that does not support the terminal handling that is required. completely portable. If the `bc` does not work on your platform, your first step should be to retry with history disabled. -### NLS (Locale Support) +#### NLS (Locale Support) To disable locale support (use only English), pass either the `-N` flag or the `--disable-nls` option to `configure.sh`, as follows: @@ -391,7 +432,7 @@ Both commands are equivalent. NLS (locale support) is automatically disabled when building for Windows or on another platform that does not support the POSIX locale API or utilities. -### Prompt +#### Prompt By default, `bc` and `dc` print a prompt when in interactive mode. They both have the command-line option `-P`/`--no-prompt`, which turns that off, but it @@ -405,7 +446,7 @@ can be disabled permanently in the build by passing the `-P` flag or the Both commands are equivalent. -### Locales +#### Locales By default, `bc` and `dc` do not install all locales, but only the enabled locales. If `DESTDIR` exists and is not empty, then they will install all of @@ -421,7 +462,7 @@ have, regardless. To enable that behavior, you can pass the `-l` flag or the Both commands are equivalent. -### Extra Math +#### Extra Math This `bc` has 7 extra operators: @@ -458,7 +499,7 @@ This `bc` also has a larger library that is only enabled if extra operators and the pseudo-random number generator are. More information about the functions can be found in the Extended Library section of the full manual. -### Manpages +#### Manpages To disable installing manpages, pass either the `-M` flag or the `--disable-man-pages` option to `configure.sh` as follows: @@ -470,7 +511,7 @@ To disable installing manpages, pass either the `-M` flag or the Both commands are equivalent. -### Karatsuba Length +#### Karatsuba Length The Karatsuba length is the point at which `bc` and `dc` switch from Karatsuba multiplication to brute force, `O(n^2)` multiplication. It can be set by passing @@ -489,7 +530,7 @@ Default is `64`. to `16` (to prevent stack overflow). If it is not, `configure.sh` will give an error. -### Install Options +#### Install Options The relevant `autotools`-style install options are supported in `configure.sh`: @@ -520,7 +561,7 @@ environment variable is overridden. other command-line options must be used. Mixing long and short options is not supported. -## Optimization +### Optimization The `configure.sh` script will accept an optimization level to pass to the compiler. Because `bc` is orders of magnitude faster with optimization, I @@ -560,7 +601,7 @@ I do **NOT*** recommend building with `-march=native`; doing so reduces this Manual stripping is not necessary; non-debug builds are automatically stripped in the link stage. -## Debug Builds +### Debug Builds Debug builds (which also disable optimization if no optimization level is given and if no extra `CFLAGS` are given) can be enabled with either the `-g` flag or @@ -580,7 +621,7 @@ make make install ``` -## Stripping Binaries +### Stripping Binaries By default, when `bc` and `dc` are not built in debug mode, the binaries are stripped. Stripping can be disabled with either the `-T` or the @@ -600,7 +641,7 @@ make make install ``` -## Binary Size +### Binary Size When built with both calculators, all available features, and `-Os` using `clang` and `musl`, the executable is 140.4 kb (140,386 bytes) on `x86_64`. That @@ -649,7 +690,7 @@ kb (107,576 bytes) without history and with extra math support, and 95.3 kb optimizations. These builds were done on an `x86_64` machine running Gentoo Linux. -## Testing +### Testing The default test suite can be run with the following command: diff --git a/manuals/dc.1.md.in b/manuals/dc.1.md.in index c5c361fe271a..56417d73f9dd 100644 --- a/manuals/dc.1.md.in +++ b/manuals/dc.1.md.in @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -82,7 +82,7 @@ The following are the options that dc(1) accepts. {{ A E H N EH EN HN EHN }} : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in **DC_ENV_ARGS**. {{ end }} @@ -92,6 +92,25 @@ The following are the options that dc(1) accepts. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +{{ A E H N EH EN HN EHN }} +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in dc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of dc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **?** command is used. +{{ end }} +{{ P EP HP NP EHP ENP HNP EHNP }} +: This option is a no-op. +{{ end }} + + This is a **non-portable extension**. + **-x** **-\-extended-register** : Enables extended register mode. See the *Extended Register Mode* subsection @@ -576,25 +595,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -761,7 +780,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -773,7 +792,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -782,7 +801,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -791,7 +810,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -800,7 +819,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -809,7 +828,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -818,7 +837,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -827,7 +846,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -836,7 +855,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -845,7 +864,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -854,7 +873,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -863,7 +882,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -919,12 +938,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/A.1 b/manuals/dc/A.1 index 7b91c02039e4..67bcf9e86d9f 100644 --- a/manuals/dc/A.1 +++ b/manuals/dc/A.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,84 +70,115 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP -\f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP -\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP -\f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. -(See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]-h\f[R], \f[B]--help\f[R] +.PP +: Prints a usage message and quits. +.PP +\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] +.PP +: Print the version information (copyright header) and exit. +.PP +\f[B]-i\f[R], \f[B]--interactive\f[R] +.PP +: Forces interactive mode. +(See the \f[B]INTERACTIVE MODE\f[R] section.) +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in \f[B]DC_ENV_ARGS\f[R]. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in dc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of dc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **?** command is used. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -190,7 +221,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -200,7 +231,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -236,13 +267,13 @@ Likewise, when a value is assigned to \f[B]seed\f[R], it is not guaranteed that querying \f[B]seed\f[R] immediately after will return the same value. In addition, the value of \f[B]seed\f[R] will change after any call to -the \f[B]\[cq]\f[R] command or the \f[B]\[dq]\f[R] command that does not +the \f[B]\[aq]\f[R] command or the \f[B]\[dq]\f[R] command that does not get receive a value of \f[B]0\f[R] or \f[B]1\f[R]. -The maximum integer returned by the \f[B]\[cq]\f[R] command can be +The maximum integer returned by the \f[B]\[aq]\f[R] command can be queried with the \f[B]W\f[R] command. .PP \f[B]Note\f[R]: The values returned by the pseudo-random number -generator with the \f[B]\[cq]\f[R] and \f[B]\[dq]\f[R] commands are +generator with the \f[B]\[aq]\f[R] and \f[B]\[dq]\f[R] commands are guaranteed to \f[B]NOT\f[R] be cryptographically secure. This is a consequence of using a seeded pseudo-random number generator. However, they \f[I]are\f[R] guaranteed to be reproducible with identical @@ -311,272 +342,340 @@ To deactivate them, just assign a different value to \f[B]obase\f[R]. .PP Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]$\f[R] -The top value is popped off the stack and copied, and the copy is -truncated and pushed onto the stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top value is popped off the stack and copied, and the copy is +truncated and pushed onto the stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The top two values are popped off the stack, and the precision of the +.PP +: The top two values are popped off the stack, and the precision of the second is set to the value of the first, whether by truncation or extension. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]H\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted left (radix shifted right) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]h\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted right (radix shifted left) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Pseudo-Random Number Generator .PP dc(1) has a built-in pseudo-random number generator. @@ -586,20 +685,24 @@ controls the pseudo-random number generator.) .PP The pseudo-random number generator is guaranteed to \f[B]NOT\f[R] be cryptographically secure. -.TP -\f[B]\[cq]\f[R] -Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive (see -the \f[B]LIMITS\f[R] section). -.RS .PP +\f[B]\[aq]\f[R] +.PP +: Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive +(see the \f[B]LIMITS\f[R] section). +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[dq]\f[R] -Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] +.PP +: Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] upper bound on the integer that will be generated. If the bound is negative or is a non-integer, an error is raised, and dc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] @@ -614,48 +717,58 @@ Using this command will change the value of \f[B]seed\f[R], unless the operand is \f[B]0\f[R] or \f[B]1\f[R]. In that case, \f[B]0\f[R] is pushed onto the stack, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.RS -.PP +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -664,113 +777,137 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and \f[B]seed\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]0\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section and the \f[B]NUMBERS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set -\f[B]scale\f[R], which must be non-negative. -.RS .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP +: Pops the value off of the top of the stack and uses it to set +\f[B]scale\f[R], which must be non-negative. +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi +.PP \f[B]j\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]seed\f[R]. The meaning of \f[B]seed\f[R] is dependent on the current pseudo-random number generator but is guaranteed to not change except for new major versions. -.RS +.IP +.nf +\f[C] +The *scale* and sign of the value may be significant. + +If a previously used **seed** value is used again, the pseudo-random number +generator is guaranteed to produce the same sequence of pseudo-random +numbers as it did when the **seed** value was previously used. + +The exact value assigned to **seed** is not guaranteed to be returned if the +**J** command is used. However, if **seed** *does* return a different value, +both values, when assigned to **seed**, are guaranteed to produce the same +sequence of pseudo-random numbers. This means that certain values assigned +to **seed** will not produce unique sequences of pseudo-random numbers. + +There is no limit to the length (number of significant decimal digits) or +*scale* of the value that can be assigned to **seed**. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The \f[I]scale\f[R] and sign of the value may be significant. -.PP -If a previously used \f[B]seed\f[R] value is used again, the -pseudo-random number generator is guaranteed to produce the same -sequence of pseudo-random numbers as it did when the \f[B]seed\f[R] -value was previously used. -.PP -The exact value assigned to \f[B]seed\f[R] is not guaranteed to be -returned if the \f[B]J\f[R] command is used. -However, if \f[B]seed\f[R] \f[I]does\f[R] return a different value, both -values, when assigned to \f[B]seed\f[R], are guaranteed to produce the -same sequence of pseudo-random numbers. -This means that certain values assigned to \f[B]seed\f[R] will not -produce unique sequences of pseudo-random numbers. -.PP -There is no limit to the length (number of significant decimal digits) -or \f[I]scale\f[R] of the value that can be assigned to \f[B]seed\f[R]. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]J\f[R] -Pushes the current value of \f[B]seed\f[R] onto the main stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the current value of \f[B]seed\f[R] onto the main stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +.PP +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]W\f[R] -Pushes the maximum (inclusive) integer that can be generated with the -\f[B]\[cq]\f[R] pseudo-random number generator command. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum (inclusive) integer that can be generated with the +\f[B]\[aq]\f[R] pseudo-random number generator command. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -787,233 +924,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -1028,8 +1224,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -1040,7 +1236,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -1085,64 +1281,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command, -if dc(1). +.PP +: The maximum integer (inclusive) returned by the \f[B]\[aq]\f[R] +command, if dc(1). Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -1152,104 +1361,117 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**H**), and right shift (**h**) +operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]H\f[R]), and right shift (\f[B]h\f[R]) operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1277,7 +1499,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1299,7 +1521,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/A.1.md b/manuals/dc/A.1.md index e53646c2fba3..8b78f48c8ded 100644 --- a/manuals/dc/A.1.md +++ b/manuals/dc/A.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -81,12 +81,26 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in **DC_ENV_ARGS**. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in dc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of dc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **?** command is used. + + This is a **non-portable extension**. + **-x** **-\-extended-register** : Enables extended register mode. See the *Extended Register Mode* subsection @@ -556,25 +570,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -723,7 +737,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -735,7 +749,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -744,7 +758,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -753,7 +767,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -762,7 +776,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -771,7 +785,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -780,7 +794,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -789,7 +803,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -798,7 +812,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -807,7 +821,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -816,7 +830,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -825,7 +839,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -881,12 +895,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/E.1 b/manuals/dc/E.1 index ebe8db87e996..e65a29fe8db2 100644 --- a/manuals/dc/E.1 +++ b/manuals/dc/E.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,84 +70,115 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP -\f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP -\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP -\f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. -(See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]-h\f[R], \f[B]--help\f[R] +.PP +: Prints a usage message and quits. +.PP +\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] +.PP +: Print the version information (copyright header) and exit. +.PP +\f[B]-i\f[R], \f[B]--interactive\f[R] +.PP +: Forces interactive mode. +(See the \f[B]INTERACTIVE MODE\f[R] section.) +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in \f[B]DC_ENV_ARGS\f[R]. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in dc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of dc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **?** command is used. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -190,7 +221,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -200,7 +231,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -242,265 +273,332 @@ The valid commands are listed below. .SS Printing .PP These commands are used for printing. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -509,68 +607,86 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]2\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]scale\f[R], which must be non-negative. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -587,233 +703,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -828,8 +1003,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -840,7 +1015,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -885,59 +1060,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -947,101 +1134,115 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1069,7 +1270,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1091,7 +1292,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/E.1.md b/manuals/dc/E.1.md index 5e0a85af9a90..641a3736878f 100644 --- a/manuals/dc/E.1.md +++ b/manuals/dc/E.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -81,12 +81,26 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in **DC_ENV_ARGS**. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in dc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of dc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **?** command is used. + + This is a **non-portable extension**. + **-x** **-\-extended-register** : Enables extended register mode. See the *Extended Register Mode* subsection @@ -432,25 +446,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -563,7 +577,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -575,7 +589,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -584,7 +598,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -593,7 +607,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -602,7 +616,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -611,7 +625,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -620,7 +634,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -629,7 +643,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -638,7 +652,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -647,7 +661,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -656,7 +670,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -665,7 +679,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -721,12 +735,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/EH.1 b/manuals/dc/EH.1 index e8e4b9069506..9676eeaba1cb 100644 --- a/manuals/dc/EH.1 +++ b/manuals/dc/EH.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,84 +70,115 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP -\f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP -\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP -\f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. -(See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]-h\f[R], \f[B]--help\f[R] +.PP +: Prints a usage message and quits. +.PP +\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] +.PP +: Print the version information (copyright header) and exit. +.PP +\f[B]-i\f[R], \f[B]--interactive\f[R] +.PP +: Forces interactive mode. +(See the \f[B]INTERACTIVE MODE\f[R] section.) +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in \f[B]DC_ENV_ARGS\f[R]. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in dc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of dc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **?** command is used. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -190,7 +221,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -200,7 +231,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -242,265 +273,332 @@ The valid commands are listed below. .SS Printing .PP These commands are used for printing. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -509,68 +607,86 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]2\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]scale\f[R], which must be non-negative. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -587,233 +703,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -828,8 +1003,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -840,7 +1015,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -885,59 +1060,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -947,101 +1134,115 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1069,7 +1270,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP The prompt is enabled in TTY mode. .PP @@ -1086,7 +1287,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/EH.1.md b/manuals/dc/EH.1.md index 6d1413d0dae4..3bdef59ef917 100644 --- a/manuals/dc/EH.1.md +++ b/manuals/dc/EH.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -81,12 +81,26 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in **DC_ENV_ARGS**. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in dc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of dc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **?** command is used. + + This is a **non-portable extension**. + **-x** **-\-extended-register** : Enables extended register mode. See the *Extended Register Mode* subsection @@ -432,25 +446,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -563,7 +577,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -575,7 +589,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -584,7 +598,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -593,7 +607,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -602,7 +616,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -611,7 +625,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -620,7 +634,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -629,7 +643,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -638,7 +652,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -647,7 +661,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -656,7 +670,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -665,7 +679,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -721,12 +735,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/EHN.1 b/manuals/dc/EHN.1 index 37f4a6656c65..8aa8f2460216 100644 --- a/manuals/dc/EHN.1 +++ b/manuals/dc/EHN.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,84 +70,115 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP -\f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP -\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP -\f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. -(See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]-h\f[R], \f[B]--help\f[R] +.PP +: Prints a usage message and quits. +.PP +\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] +.PP +: Print the version information (copyright header) and exit. +.PP +\f[B]-i\f[R], \f[B]--interactive\f[R] +.PP +: Forces interactive mode. +(See the \f[B]INTERACTIVE MODE\f[R] section.) +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in \f[B]DC_ENV_ARGS\f[R]. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in dc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of dc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **?** command is used. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -190,7 +221,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -200,7 +231,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -242,265 +273,332 @@ The valid commands are listed below. .SS Printing .PP These commands are used for printing. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -509,68 +607,86 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]2\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]scale\f[R], which must be non-negative. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -587,233 +703,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -828,8 +1003,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -840,7 +1015,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -885,59 +1060,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -947,101 +1134,115 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1069,7 +1270,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP The prompt is enabled in TTY mode. .PP @@ -1086,7 +1287,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/EHN.1.md b/manuals/dc/EHN.1.md index 2e24a10a06dc..fc49cc7187c3 100644 --- a/manuals/dc/EHN.1.md +++ b/manuals/dc/EHN.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -81,12 +81,26 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in **DC_ENV_ARGS**. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in dc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of dc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **?** command is used. + + This is a **non-portable extension**. + **-x** **-\-extended-register** : Enables extended register mode. See the *Extended Register Mode* subsection @@ -432,25 +446,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -563,7 +577,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -575,7 +589,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -584,7 +598,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -593,7 +607,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -602,7 +616,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -611,7 +625,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -620,7 +634,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -629,7 +643,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -638,7 +652,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -647,7 +661,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -656,7 +670,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -665,7 +679,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -721,12 +735,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/EHNP.1 b/manuals/dc/EHNP.1 index f0ea848f819b..be491096703f 100644 --- a/manuals/dc/EHNP.1 +++ b/manuals/dc/EHNP.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,79 +70,100 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP +.PP +: Print the version information (copyright header) and exit. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -185,7 +206,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -195,7 +216,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -237,265 +258,332 @@ The valid commands are listed below. .SS Printing .PP These commands are used for printing. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -504,68 +592,86 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]2\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]scale\f[R], which must be non-negative. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -582,233 +688,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -823,8 +988,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -835,7 +1000,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -880,59 +1045,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -942,101 +1119,115 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1064,7 +1255,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is different from interactive mode because interactive mode is required in the bc(1) @@ -1079,7 +1270,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/EHNP.1.md b/manuals/dc/EHNP.1.md index 5abed62294c2..edbf30b272e1 100644 --- a/manuals/dc/EHNP.1.md +++ b/manuals/dc/EHNP.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -80,6 +80,12 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** +: This option is a no-op. + + This is a **non-portable extension**. + +**-R**, **-\-no-read-prompt** + : This option is a no-op. This is a **non-portable extension**. @@ -429,25 +435,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -560,7 +566,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -572,7 +578,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -581,7 +587,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -590,7 +596,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -599,7 +605,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -608,7 +614,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -617,7 +623,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -626,7 +632,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -635,7 +641,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -644,7 +650,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -653,7 +659,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -662,7 +668,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -718,12 +724,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/EHP.1 b/manuals/dc/EHP.1 index 654c24309c56..797f0ef2bcfb 100644 --- a/manuals/dc/EHP.1 +++ b/manuals/dc/EHP.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,79 +70,100 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP +.PP +: Print the version information (copyright header) and exit. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -185,7 +206,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -195,7 +216,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -237,265 +258,332 @@ The valid commands are listed below. .SS Printing .PP These commands are used for printing. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -504,68 +592,86 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]2\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]scale\f[R], which must be non-negative. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -582,233 +688,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -823,8 +988,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -835,7 +1000,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -880,59 +1045,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -942,101 +1119,115 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1064,7 +1255,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is different from interactive mode because interactive mode is required in the bc(1) @@ -1079,7 +1270,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/EHP.1.md b/manuals/dc/EHP.1.md index 17ebe0420492..d890cc3a0c72 100644 --- a/manuals/dc/EHP.1.md +++ b/manuals/dc/EHP.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -80,6 +80,12 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** +: This option is a no-op. + + This is a **non-portable extension**. + +**-R**, **-\-no-read-prompt** + : This option is a no-op. This is a **non-portable extension**. @@ -429,25 +435,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -560,7 +566,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -572,7 +578,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -581,7 +587,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -590,7 +596,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -599,7 +605,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -608,7 +614,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -617,7 +623,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -626,7 +632,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -635,7 +641,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -644,7 +650,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -653,7 +659,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -662,7 +668,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -718,12 +724,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/EN.1 b/manuals/dc/EN.1 index 6d522efdde45..242306dab617 100644 --- a/manuals/dc/EN.1 +++ b/manuals/dc/EN.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,84 +70,115 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP -\f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP -\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP -\f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. -(See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]-h\f[R], \f[B]--help\f[R] +.PP +: Prints a usage message and quits. +.PP +\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] +.PP +: Print the version information (copyright header) and exit. +.PP +\f[B]-i\f[R], \f[B]--interactive\f[R] +.PP +: Forces interactive mode. +(See the \f[B]INTERACTIVE MODE\f[R] section.) +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in \f[B]DC_ENV_ARGS\f[R]. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in dc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of dc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **?** command is used. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -190,7 +221,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -200,7 +231,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -242,265 +273,332 @@ The valid commands are listed below. .SS Printing .PP These commands are used for printing. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -509,68 +607,86 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]2\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]scale\f[R], which must be non-negative. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -587,233 +703,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -828,8 +1003,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -840,7 +1015,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -885,59 +1060,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -947,101 +1134,115 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1069,7 +1270,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1091,7 +1292,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/EN.1.md b/manuals/dc/EN.1.md index 4c0297fdab7f..dbd7e8d8e52d 100644 --- a/manuals/dc/EN.1.md +++ b/manuals/dc/EN.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -81,12 +81,26 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in **DC_ENV_ARGS**. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in dc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of dc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **?** command is used. + + This is a **non-portable extension**. + **-x** **-\-extended-register** : Enables extended register mode. See the *Extended Register Mode* subsection @@ -432,25 +446,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -563,7 +577,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -575,7 +589,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -584,7 +598,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -593,7 +607,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -602,7 +616,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -611,7 +625,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -620,7 +634,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -629,7 +643,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -638,7 +652,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -647,7 +661,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -656,7 +670,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -665,7 +679,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -721,12 +735,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/ENP.1 b/manuals/dc/ENP.1 index c9659423dc26..4f23bebed353 100644 --- a/manuals/dc/ENP.1 +++ b/manuals/dc/ENP.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,79 +70,100 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP +.PP +: Print the version information (copyright header) and exit. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -185,7 +206,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -195,7 +216,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -237,265 +258,332 @@ The valid commands are listed below. .SS Printing .PP These commands are used for printing. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -504,68 +592,86 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]2\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]scale\f[R], which must be non-negative. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -582,233 +688,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -823,8 +988,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -835,7 +1000,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -880,59 +1045,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -942,101 +1119,115 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1064,7 +1255,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1084,7 +1275,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/ENP.1.md b/manuals/dc/ENP.1.md index 4025c643b956..a2facd8d8cdd 100644 --- a/manuals/dc/ENP.1.md +++ b/manuals/dc/ENP.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -80,6 +80,12 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** +: This option is a no-op. + + This is a **non-portable extension**. + +**-R**, **-\-no-read-prompt** + : This option is a no-op. This is a **non-portable extension**. @@ -429,25 +435,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -560,7 +566,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -572,7 +578,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -581,7 +587,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -590,7 +596,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -599,7 +605,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -608,7 +614,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -617,7 +623,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -626,7 +632,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -635,7 +641,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -644,7 +650,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -653,7 +659,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -662,7 +668,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -718,12 +724,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/EP.1 b/manuals/dc/EP.1 index 1dd0da3235e7..ad6277c249b0 100644 --- a/manuals/dc/EP.1 +++ b/manuals/dc/EP.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,79 +70,100 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP +.PP +: Print the version information (copyright header) and exit. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -185,7 +206,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -195,7 +216,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -237,265 +258,332 @@ The valid commands are listed below. .SS Printing .PP These commands are used for printing. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -504,68 +592,86 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], and \f[B]scale\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]2\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]scale\f[R], which must be non-negative. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -582,233 +688,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -823,8 +988,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -835,7 +1000,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -880,59 +1045,71 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -942,101 +1119,115 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**) operator. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, attempting to convert a negative number to a hardware -integer, overflow when converting a number to a hardware integer, and -attempting to use a non-integer where an integer is required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]) operator. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1064,7 +1255,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1084,7 +1275,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/EP.1.md b/manuals/dc/EP.1.md index fcb15291262d..32b7f35fe92e 100644 --- a/manuals/dc/EP.1.md +++ b/manuals/dc/EP.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -80,6 +80,12 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** +: This option is a no-op. + + This is a **non-portable extension**. + +**-R**, **-\-no-read-prompt** + : This option is a no-op. This is a **non-portable extension**. @@ -429,25 +435,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -560,7 +566,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -572,7 +578,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -581,7 +587,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -590,7 +596,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -599,7 +605,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -608,7 +614,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -617,7 +623,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -626,7 +632,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -635,7 +641,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -644,7 +650,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -653,7 +659,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -662,7 +668,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -718,12 +724,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/H.1 b/manuals/dc/H.1 index 15fe0edb0d2d..9d7ef21b3d1f 100644 --- a/manuals/dc/H.1 +++ b/manuals/dc/H.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,84 +70,115 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP -\f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP -\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP -\f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. -(See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]-h\f[R], \f[B]--help\f[R] +.PP +: Prints a usage message and quits. +.PP +\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] +.PP +: Print the version information (copyright header) and exit. +.PP +\f[B]-i\f[R], \f[B]--interactive\f[R] +.PP +: Forces interactive mode. +(See the \f[B]INTERACTIVE MODE\f[R] section.) +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in \f[B]DC_ENV_ARGS\f[R]. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in dc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of dc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **?** command is used. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -190,7 +221,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -200,7 +231,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -236,13 +267,13 @@ Likewise, when a value is assigned to \f[B]seed\f[R], it is not guaranteed that querying \f[B]seed\f[R] immediately after will return the same value. In addition, the value of \f[B]seed\f[R] will change after any call to -the \f[B]\[cq]\f[R] command or the \f[B]\[dq]\f[R] command that does not +the \f[B]\[aq]\f[R] command or the \f[B]\[dq]\f[R] command that does not get receive a value of \f[B]0\f[R] or \f[B]1\f[R]. -The maximum integer returned by the \f[B]\[cq]\f[R] command can be +The maximum integer returned by the \f[B]\[aq]\f[R] command can be queried with the \f[B]W\f[R] command. .PP \f[B]Note\f[R]: The values returned by the pseudo-random number -generator with the \f[B]\[cq]\f[R] and \f[B]\[dq]\f[R] commands are +generator with the \f[B]\[aq]\f[R] and \f[B]\[dq]\f[R] commands are guaranteed to \f[B]NOT\f[R] be cryptographically secure. This is a consequence of using a seeded pseudo-random number generator. However, they \f[I]are\f[R] guaranteed to be reproducible with identical @@ -311,272 +342,340 @@ To deactivate them, just assign a different value to \f[B]obase\f[R]. .PP Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]$\f[R] -The top value is popped off the stack and copied, and the copy is -truncated and pushed onto the stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top value is popped off the stack and copied, and the copy is +truncated and pushed onto the stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The top two values are popped off the stack, and the precision of the +.PP +: The top two values are popped off the stack, and the precision of the second is set to the value of the first, whether by truncation or extension. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]H\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted left (radix shifted right) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]h\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted right (radix shifted left) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Pseudo-Random Number Generator .PP dc(1) has a built-in pseudo-random number generator. @@ -586,20 +685,24 @@ controls the pseudo-random number generator.) .PP The pseudo-random number generator is guaranteed to \f[B]NOT\f[R] be cryptographically secure. -.TP -\f[B]\[cq]\f[R] -Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive (see -the \f[B]LIMITS\f[R] section). -.RS .PP +\f[B]\[aq]\f[R] +.PP +: Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive +(see the \f[B]LIMITS\f[R] section). +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[dq]\f[R] -Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] +.PP +: Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] upper bound on the integer that will be generated. If the bound is negative or is a non-integer, an error is raised, and dc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] @@ -614,48 +717,58 @@ Using this command will change the value of \f[B]seed\f[R], unless the operand is \f[B]0\f[R] or \f[B]1\f[R]. In that case, \f[B]0\f[R] is pushed onto the stack, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.RS -.PP +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -664,113 +777,137 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and \f[B]seed\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]0\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section and the \f[B]NUMBERS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set -\f[B]scale\f[R], which must be non-negative. -.RS .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP +: Pops the value off of the top of the stack and uses it to set +\f[B]scale\f[R], which must be non-negative. +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi +.PP \f[B]j\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]seed\f[R]. The meaning of \f[B]seed\f[R] is dependent on the current pseudo-random number generator but is guaranteed to not change except for new major versions. -.RS +.IP +.nf +\f[C] +The *scale* and sign of the value may be significant. + +If a previously used **seed** value is used again, the pseudo-random number +generator is guaranteed to produce the same sequence of pseudo-random +numbers as it did when the **seed** value was previously used. + +The exact value assigned to **seed** is not guaranteed to be returned if the +**J** command is used. However, if **seed** *does* return a different value, +both values, when assigned to **seed**, are guaranteed to produce the same +sequence of pseudo-random numbers. This means that certain values assigned +to **seed** will not produce unique sequences of pseudo-random numbers. + +There is no limit to the length (number of significant decimal digits) or +*scale* of the value that can be assigned to **seed**. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The \f[I]scale\f[R] and sign of the value may be significant. -.PP -If a previously used \f[B]seed\f[R] value is used again, the -pseudo-random number generator is guaranteed to produce the same -sequence of pseudo-random numbers as it did when the \f[B]seed\f[R] -value was previously used. -.PP -The exact value assigned to \f[B]seed\f[R] is not guaranteed to be -returned if the \f[B]J\f[R] command is used. -However, if \f[B]seed\f[R] \f[I]does\f[R] return a different value, both -values, when assigned to \f[B]seed\f[R], are guaranteed to produce the -same sequence of pseudo-random numbers. -This means that certain values assigned to \f[B]seed\f[R] will not -produce unique sequences of pseudo-random numbers. -.PP -There is no limit to the length (number of significant decimal digits) -or \f[I]scale\f[R] of the value that can be assigned to \f[B]seed\f[R]. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]J\f[R] -Pushes the current value of \f[B]seed\f[R] onto the main stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the current value of \f[B]seed\f[R] onto the main stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +.PP +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]W\f[R] -Pushes the maximum (inclusive) integer that can be generated with the -\f[B]\[cq]\f[R] pseudo-random number generator command. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum (inclusive) integer that can be generated with the +\f[B]\[aq]\f[R] pseudo-random number generator command. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -787,233 +924,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -1028,8 +1224,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -1040,7 +1236,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -1085,64 +1281,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command, -if dc(1). +.PP +: The maximum integer (inclusive) returned by the \f[B]\[aq]\f[R] +command, if dc(1). Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -1152,104 +1361,117 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**H**), and right shift (**h**) +operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]H\f[R]), and right shift (\f[B]h\f[R]) operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1277,7 +1499,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP The prompt is enabled in TTY mode. .PP @@ -1294,7 +1516,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/H.1.md b/manuals/dc/H.1.md index de83e3088f9c..0114f7556a49 100644 --- a/manuals/dc/H.1.md +++ b/manuals/dc/H.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -81,12 +81,26 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in **DC_ENV_ARGS**. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in dc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of dc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **?** command is used. + + This is a **non-portable extension**. + **-x** **-\-extended-register** : Enables extended register mode. See the *Extended Register Mode* subsection @@ -556,25 +570,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -723,7 +737,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -735,7 +749,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -744,7 +758,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -753,7 +767,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -762,7 +776,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -771,7 +785,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -780,7 +794,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -789,7 +803,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -798,7 +812,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -807,7 +821,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -816,7 +830,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -825,7 +839,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -881,12 +895,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/HN.1 b/manuals/dc/HN.1 index a617bb473ec1..c04b7463f6bc 100644 --- a/manuals/dc/HN.1 +++ b/manuals/dc/HN.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,84 +70,115 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP -\f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP -\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP -\f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. -(See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]-h\f[R], \f[B]--help\f[R] +.PP +: Prints a usage message and quits. +.PP +\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] +.PP +: Print the version information (copyright header) and exit. +.PP +\f[B]-i\f[R], \f[B]--interactive\f[R] +.PP +: Forces interactive mode. +(See the \f[B]INTERACTIVE MODE\f[R] section.) +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in \f[B]DC_ENV_ARGS\f[R]. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in dc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of dc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **?** command is used. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -190,7 +221,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -200,7 +231,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -236,13 +267,13 @@ Likewise, when a value is assigned to \f[B]seed\f[R], it is not guaranteed that querying \f[B]seed\f[R] immediately after will return the same value. In addition, the value of \f[B]seed\f[R] will change after any call to -the \f[B]\[cq]\f[R] command or the \f[B]\[dq]\f[R] command that does not +the \f[B]\[aq]\f[R] command or the \f[B]\[dq]\f[R] command that does not get receive a value of \f[B]0\f[R] or \f[B]1\f[R]. -The maximum integer returned by the \f[B]\[cq]\f[R] command can be +The maximum integer returned by the \f[B]\[aq]\f[R] command can be queried with the \f[B]W\f[R] command. .PP \f[B]Note\f[R]: The values returned by the pseudo-random number -generator with the \f[B]\[cq]\f[R] and \f[B]\[dq]\f[R] commands are +generator with the \f[B]\[aq]\f[R] and \f[B]\[dq]\f[R] commands are guaranteed to \f[B]NOT\f[R] be cryptographically secure. This is a consequence of using a seeded pseudo-random number generator. However, they \f[I]are\f[R] guaranteed to be reproducible with identical @@ -311,272 +342,340 @@ To deactivate them, just assign a different value to \f[B]obase\f[R]. .PP Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]$\f[R] -The top value is popped off the stack and copied, and the copy is -truncated and pushed onto the stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top value is popped off the stack and copied, and the copy is +truncated and pushed onto the stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The top two values are popped off the stack, and the precision of the +.PP +: The top two values are popped off the stack, and the precision of the second is set to the value of the first, whether by truncation or extension. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]H\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted left (radix shifted right) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]h\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted right (radix shifted left) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Pseudo-Random Number Generator .PP dc(1) has a built-in pseudo-random number generator. @@ -586,20 +685,24 @@ controls the pseudo-random number generator.) .PP The pseudo-random number generator is guaranteed to \f[B]NOT\f[R] be cryptographically secure. -.TP -\f[B]\[cq]\f[R] -Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive (see -the \f[B]LIMITS\f[R] section). -.RS .PP +\f[B]\[aq]\f[R] +.PP +: Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive +(see the \f[B]LIMITS\f[R] section). +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[dq]\f[R] -Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] +.PP +: Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] upper bound on the integer that will be generated. If the bound is negative or is a non-integer, an error is raised, and dc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] @@ -614,48 +717,58 @@ Using this command will change the value of \f[B]seed\f[R], unless the operand is \f[B]0\f[R] or \f[B]1\f[R]. In that case, \f[B]0\f[R] is pushed onto the stack, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.RS -.PP +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -664,113 +777,137 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and \f[B]seed\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]0\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section and the \f[B]NUMBERS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set -\f[B]scale\f[R], which must be non-negative. -.RS .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP +: Pops the value off of the top of the stack and uses it to set +\f[B]scale\f[R], which must be non-negative. +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi +.PP \f[B]j\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]seed\f[R]. The meaning of \f[B]seed\f[R] is dependent on the current pseudo-random number generator but is guaranteed to not change except for new major versions. -.RS +.IP +.nf +\f[C] +The *scale* and sign of the value may be significant. + +If a previously used **seed** value is used again, the pseudo-random number +generator is guaranteed to produce the same sequence of pseudo-random +numbers as it did when the **seed** value was previously used. + +The exact value assigned to **seed** is not guaranteed to be returned if the +**J** command is used. However, if **seed** *does* return a different value, +both values, when assigned to **seed**, are guaranteed to produce the same +sequence of pseudo-random numbers. This means that certain values assigned +to **seed** will not produce unique sequences of pseudo-random numbers. + +There is no limit to the length (number of significant decimal digits) or +*scale* of the value that can be assigned to **seed**. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The \f[I]scale\f[R] and sign of the value may be significant. -.PP -If a previously used \f[B]seed\f[R] value is used again, the -pseudo-random number generator is guaranteed to produce the same -sequence of pseudo-random numbers as it did when the \f[B]seed\f[R] -value was previously used. -.PP -The exact value assigned to \f[B]seed\f[R] is not guaranteed to be -returned if the \f[B]J\f[R] command is used. -However, if \f[B]seed\f[R] \f[I]does\f[R] return a different value, both -values, when assigned to \f[B]seed\f[R], are guaranteed to produce the -same sequence of pseudo-random numbers. -This means that certain values assigned to \f[B]seed\f[R] will not -produce unique sequences of pseudo-random numbers. -.PP -There is no limit to the length (number of significant decimal digits) -or \f[I]scale\f[R] of the value that can be assigned to \f[B]seed\f[R]. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]J\f[R] -Pushes the current value of \f[B]seed\f[R] onto the main stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the current value of \f[B]seed\f[R] onto the main stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +.PP +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]W\f[R] -Pushes the maximum (inclusive) integer that can be generated with the -\f[B]\[cq]\f[R] pseudo-random number generator command. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum (inclusive) integer that can be generated with the +\f[B]\[aq]\f[R] pseudo-random number generator command. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -787,233 +924,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -1028,8 +1224,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -1040,7 +1236,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -1085,64 +1281,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command, -if dc(1). +.PP +: The maximum integer (inclusive) returned by the \f[B]\[aq]\f[R] +command, if dc(1). Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -1152,104 +1361,117 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**H**), and right shift (**h**) +operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]H\f[R]), and right shift (\f[B]h\f[R]) operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1277,7 +1499,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP The prompt is enabled in TTY mode. .PP @@ -1294,7 +1516,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/HN.1.md b/manuals/dc/HN.1.md index 005579cd02c8..92f040cffb13 100644 --- a/manuals/dc/HN.1.md +++ b/manuals/dc/HN.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -81,12 +81,26 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in **DC_ENV_ARGS**. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in dc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of dc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **?** command is used. + + This is a **non-portable extension**. + **-x** **-\-extended-register** : Enables extended register mode. See the *Extended Register Mode* subsection @@ -556,25 +570,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -723,7 +737,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -735,7 +749,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -744,7 +758,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -753,7 +767,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -762,7 +776,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -771,7 +785,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -780,7 +794,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -789,7 +803,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -798,7 +812,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -807,7 +821,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -816,7 +830,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -825,7 +839,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -881,12 +895,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/HNP.1 b/manuals/dc/HNP.1 index 7eb4b8b19f3d..bec07f5ad64f 100644 --- a/manuals/dc/HNP.1 +++ b/manuals/dc/HNP.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,79 +70,100 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP +.PP +: Print the version information (copyright header) and exit. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -185,7 +206,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -195,7 +216,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -231,13 +252,13 @@ Likewise, when a value is assigned to \f[B]seed\f[R], it is not guaranteed that querying \f[B]seed\f[R] immediately after will return the same value. In addition, the value of \f[B]seed\f[R] will change after any call to -the \f[B]\[cq]\f[R] command or the \f[B]\[dq]\f[R] command that does not +the \f[B]\[aq]\f[R] command or the \f[B]\[dq]\f[R] command that does not get receive a value of \f[B]0\f[R] or \f[B]1\f[R]. -The maximum integer returned by the \f[B]\[cq]\f[R] command can be +The maximum integer returned by the \f[B]\[aq]\f[R] command can be queried with the \f[B]W\f[R] command. .PP \f[B]Note\f[R]: The values returned by the pseudo-random number -generator with the \f[B]\[cq]\f[R] and \f[B]\[dq]\f[R] commands are +generator with the \f[B]\[aq]\f[R] and \f[B]\[dq]\f[R] commands are guaranteed to \f[B]NOT\f[R] be cryptographically secure. This is a consequence of using a seeded pseudo-random number generator. However, they \f[I]are\f[R] guaranteed to be reproducible with identical @@ -306,272 +327,340 @@ To deactivate them, just assign a different value to \f[B]obase\f[R]. .PP Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]$\f[R] -The top value is popped off the stack and copied, and the copy is -truncated and pushed onto the stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top value is popped off the stack and copied, and the copy is +truncated and pushed onto the stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The top two values are popped off the stack, and the precision of the +.PP +: The top two values are popped off the stack, and the precision of the second is set to the value of the first, whether by truncation or extension. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]H\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted left (radix shifted right) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]h\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted right (radix shifted left) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Pseudo-Random Number Generator .PP dc(1) has a built-in pseudo-random number generator. @@ -581,20 +670,24 @@ controls the pseudo-random number generator.) .PP The pseudo-random number generator is guaranteed to \f[B]NOT\f[R] be cryptographically secure. -.TP -\f[B]\[cq]\f[R] -Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive (see -the \f[B]LIMITS\f[R] section). -.RS .PP +\f[B]\[aq]\f[R] +.PP +: Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive +(see the \f[B]LIMITS\f[R] section). +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[dq]\f[R] -Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] +.PP +: Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] upper bound on the integer that will be generated. If the bound is negative or is a non-integer, an error is raised, and dc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] @@ -609,48 +702,58 @@ Using this command will change the value of \f[B]seed\f[R], unless the operand is \f[B]0\f[R] or \f[B]1\f[R]. In that case, \f[B]0\f[R] is pushed onto the stack, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.RS -.PP +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -659,113 +762,137 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and \f[B]seed\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]0\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section and the \f[B]NUMBERS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set -\f[B]scale\f[R], which must be non-negative. -.RS .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP +: Pops the value off of the top of the stack and uses it to set +\f[B]scale\f[R], which must be non-negative. +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi +.PP \f[B]j\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]seed\f[R]. The meaning of \f[B]seed\f[R] is dependent on the current pseudo-random number generator but is guaranteed to not change except for new major versions. -.RS +.IP +.nf +\f[C] +The *scale* and sign of the value may be significant. + +If a previously used **seed** value is used again, the pseudo-random number +generator is guaranteed to produce the same sequence of pseudo-random +numbers as it did when the **seed** value was previously used. + +The exact value assigned to **seed** is not guaranteed to be returned if the +**J** command is used. However, if **seed** *does* return a different value, +both values, when assigned to **seed**, are guaranteed to produce the same +sequence of pseudo-random numbers. This means that certain values assigned +to **seed** will not produce unique sequences of pseudo-random numbers. + +There is no limit to the length (number of significant decimal digits) or +*scale* of the value that can be assigned to **seed**. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The \f[I]scale\f[R] and sign of the value may be significant. -.PP -If a previously used \f[B]seed\f[R] value is used again, the -pseudo-random number generator is guaranteed to produce the same -sequence of pseudo-random numbers as it did when the \f[B]seed\f[R] -value was previously used. -.PP -The exact value assigned to \f[B]seed\f[R] is not guaranteed to be -returned if the \f[B]J\f[R] command is used. -However, if \f[B]seed\f[R] \f[I]does\f[R] return a different value, both -values, when assigned to \f[B]seed\f[R], are guaranteed to produce the -same sequence of pseudo-random numbers. -This means that certain values assigned to \f[B]seed\f[R] will not -produce unique sequences of pseudo-random numbers. -.PP -There is no limit to the length (number of significant decimal digits) -or \f[I]scale\f[R] of the value that can be assigned to \f[B]seed\f[R]. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]J\f[R] -Pushes the current value of \f[B]seed\f[R] onto the main stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the current value of \f[B]seed\f[R] onto the main stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +.PP +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]W\f[R] -Pushes the maximum (inclusive) integer that can be generated with the -\f[B]\[cq]\f[R] pseudo-random number generator command. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum (inclusive) integer that can be generated with the +\f[B]\[aq]\f[R] pseudo-random number generator command. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -782,233 +909,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -1023,8 +1209,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -1035,7 +1221,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -1080,64 +1266,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command, -if dc(1). +.PP +: The maximum integer (inclusive) returned by the \f[B]\[aq]\f[R] +command, if dc(1). Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -1147,104 +1346,117 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**H**), and right shift (**h**) +operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]H\f[R]), and right shift (\f[B]h\f[R]) operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1272,7 +1484,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is different from interactive mode because interactive mode is required in the bc(1) @@ -1287,7 +1499,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/HNP.1.md b/manuals/dc/HNP.1.md index d099d6f9cdcf..a93b3271ec85 100644 --- a/manuals/dc/HNP.1.md +++ b/manuals/dc/HNP.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -80,6 +80,12 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** +: This option is a no-op. + + This is a **non-portable extension**. + +**-R**, **-\-no-read-prompt** + : This option is a no-op. This is a **non-portable extension**. @@ -553,25 +559,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -720,7 +726,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -732,7 +738,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -741,7 +747,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -750,7 +756,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -759,7 +765,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -768,7 +774,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -777,7 +783,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -786,7 +792,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -795,7 +801,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -804,7 +810,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -813,7 +819,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -822,7 +828,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -878,12 +884,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/HP.1 b/manuals/dc/HP.1 index cea646c8a3f3..a28ee9a9cae2 100644 --- a/manuals/dc/HP.1 +++ b/manuals/dc/HP.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,79 +70,100 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP +.PP +: Print the version information (copyright header) and exit. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -185,7 +206,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -195,7 +216,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -231,13 +252,13 @@ Likewise, when a value is assigned to \f[B]seed\f[R], it is not guaranteed that querying \f[B]seed\f[R] immediately after will return the same value. In addition, the value of \f[B]seed\f[R] will change after any call to -the \f[B]\[cq]\f[R] command or the \f[B]\[dq]\f[R] command that does not +the \f[B]\[aq]\f[R] command or the \f[B]\[dq]\f[R] command that does not get receive a value of \f[B]0\f[R] or \f[B]1\f[R]. -The maximum integer returned by the \f[B]\[cq]\f[R] command can be +The maximum integer returned by the \f[B]\[aq]\f[R] command can be queried with the \f[B]W\f[R] command. .PP \f[B]Note\f[R]: The values returned by the pseudo-random number -generator with the \f[B]\[cq]\f[R] and \f[B]\[dq]\f[R] commands are +generator with the \f[B]\[aq]\f[R] and \f[B]\[dq]\f[R] commands are guaranteed to \f[B]NOT\f[R] be cryptographically secure. This is a consequence of using a seeded pseudo-random number generator. However, they \f[I]are\f[R] guaranteed to be reproducible with identical @@ -306,272 +327,340 @@ To deactivate them, just assign a different value to \f[B]obase\f[R]. .PP Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]$\f[R] -The top value is popped off the stack and copied, and the copy is -truncated and pushed onto the stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top value is popped off the stack and copied, and the copy is +truncated and pushed onto the stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The top two values are popped off the stack, and the precision of the +.PP +: The top two values are popped off the stack, and the precision of the second is set to the value of the first, whether by truncation or extension. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]H\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted left (radix shifted right) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]h\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted right (radix shifted left) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Pseudo-Random Number Generator .PP dc(1) has a built-in pseudo-random number generator. @@ -581,20 +670,24 @@ controls the pseudo-random number generator.) .PP The pseudo-random number generator is guaranteed to \f[B]NOT\f[R] be cryptographically secure. -.TP -\f[B]\[cq]\f[R] -Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive (see -the \f[B]LIMITS\f[R] section). -.RS .PP +\f[B]\[aq]\f[R] +.PP +: Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive +(see the \f[B]LIMITS\f[R] section). +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[dq]\f[R] -Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] +.PP +: Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] upper bound on the integer that will be generated. If the bound is negative or is a non-integer, an error is raised, and dc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] @@ -609,48 +702,58 @@ Using this command will change the value of \f[B]seed\f[R], unless the operand is \f[B]0\f[R] or \f[B]1\f[R]. In that case, \f[B]0\f[R] is pushed onto the stack, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.RS -.PP +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -659,113 +762,137 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and \f[B]seed\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]0\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section and the \f[B]NUMBERS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set -\f[B]scale\f[R], which must be non-negative. -.RS .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP +: Pops the value off of the top of the stack and uses it to set +\f[B]scale\f[R], which must be non-negative. +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi +.PP \f[B]j\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]seed\f[R]. The meaning of \f[B]seed\f[R] is dependent on the current pseudo-random number generator but is guaranteed to not change except for new major versions. -.RS +.IP +.nf +\f[C] +The *scale* and sign of the value may be significant. + +If a previously used **seed** value is used again, the pseudo-random number +generator is guaranteed to produce the same sequence of pseudo-random +numbers as it did when the **seed** value was previously used. + +The exact value assigned to **seed** is not guaranteed to be returned if the +**J** command is used. However, if **seed** *does* return a different value, +both values, when assigned to **seed**, are guaranteed to produce the same +sequence of pseudo-random numbers. This means that certain values assigned +to **seed** will not produce unique sequences of pseudo-random numbers. + +There is no limit to the length (number of significant decimal digits) or +*scale* of the value that can be assigned to **seed**. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The \f[I]scale\f[R] and sign of the value may be significant. -.PP -If a previously used \f[B]seed\f[R] value is used again, the -pseudo-random number generator is guaranteed to produce the same -sequence of pseudo-random numbers as it did when the \f[B]seed\f[R] -value was previously used. -.PP -The exact value assigned to \f[B]seed\f[R] is not guaranteed to be -returned if the \f[B]J\f[R] command is used. -However, if \f[B]seed\f[R] \f[I]does\f[R] return a different value, both -values, when assigned to \f[B]seed\f[R], are guaranteed to produce the -same sequence of pseudo-random numbers. -This means that certain values assigned to \f[B]seed\f[R] will not -produce unique sequences of pseudo-random numbers. -.PP -There is no limit to the length (number of significant decimal digits) -or \f[I]scale\f[R] of the value that can be assigned to \f[B]seed\f[R]. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]J\f[R] -Pushes the current value of \f[B]seed\f[R] onto the main stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the current value of \f[B]seed\f[R] onto the main stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +.PP +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]W\f[R] -Pushes the maximum (inclusive) integer that can be generated with the -\f[B]\[cq]\f[R] pseudo-random number generator command. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum (inclusive) integer that can be generated with the +\f[B]\[aq]\f[R] pseudo-random number generator command. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -782,233 +909,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -1023,8 +1209,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -1035,7 +1221,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -1080,64 +1266,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command, -if dc(1). +.PP +: The maximum integer (inclusive) returned by the \f[B]\[aq]\f[R] +command, if dc(1). Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -1147,104 +1346,117 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**H**), and right shift (**h**) +operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]H\f[R]), and right shift (\f[B]h\f[R]) operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1272,7 +1484,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is different from interactive mode because interactive mode is required in the bc(1) @@ -1287,7 +1499,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/HP.1.md b/manuals/dc/HP.1.md index 93938790f460..dcc59f1896d5 100644 --- a/manuals/dc/HP.1.md +++ b/manuals/dc/HP.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -80,6 +80,12 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** +: This option is a no-op. + + This is a **non-portable extension**. + +**-R**, **-\-no-read-prompt** + : This option is a no-op. This is a **non-portable extension**. @@ -553,25 +559,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -720,7 +726,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -732,7 +738,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -741,7 +747,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -750,7 +756,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -759,7 +765,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -768,7 +774,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -777,7 +783,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -786,7 +792,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -795,7 +801,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -804,7 +810,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -813,7 +819,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -822,7 +828,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -878,12 +884,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/N.1 b/manuals/dc/N.1 index 6f4f01c48354..41cc7449c3a6 100644 --- a/manuals/dc/N.1 +++ b/manuals/dc/N.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,84 +70,115 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP -\f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP -\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP -\f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. -(See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +\f[B]-h\f[R], \f[B]--help\f[R] +.PP +: Prints a usage message and quits. +.PP +\f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] +.PP +: Print the version information (copyright header) and exit. +.PP +\f[B]-i\f[R], \f[B]--interactive\f[R] +.PP +: Forces interactive mode. +(See the \f[B]INTERACTIVE MODE\f[R] section.) +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -Disables the prompt in TTY mode. +.PP +: Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. -See the \f[B]TTY MODE\f[R] section) This is mostly for those users that +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in \f[B]DC_ENV_ARGS\f[R]. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: Disables the read prompt in TTY mode. +(The read prompt is only enabled in TTY mode. +See the \f[B]TTY MODE\f[R] section.) This is mostly for those users that +do not want a read prompt or are not used to having them in dc(1). +Most of those users would want to put this option in +\f[B]BC_ENV_ARGS\f[R] (see the \f[B]ENVIRONMENT VARIABLES\f[R] section). +This option is also useful in hash bang lines of dc(1) scripts that +prompt for user input. +.IP +.nf +\f[C] +This option does not disable the regular prompt because the read prompt is +only used when the **?** command is used. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -190,7 +221,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -200,7 +231,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -236,13 +267,13 @@ Likewise, when a value is assigned to \f[B]seed\f[R], it is not guaranteed that querying \f[B]seed\f[R] immediately after will return the same value. In addition, the value of \f[B]seed\f[R] will change after any call to -the \f[B]\[cq]\f[R] command or the \f[B]\[dq]\f[R] command that does not +the \f[B]\[aq]\f[R] command or the \f[B]\[dq]\f[R] command that does not get receive a value of \f[B]0\f[R] or \f[B]1\f[R]. -The maximum integer returned by the \f[B]\[cq]\f[R] command can be +The maximum integer returned by the \f[B]\[aq]\f[R] command can be queried with the \f[B]W\f[R] command. .PP \f[B]Note\f[R]: The values returned by the pseudo-random number -generator with the \f[B]\[cq]\f[R] and \f[B]\[dq]\f[R] commands are +generator with the \f[B]\[aq]\f[R] and \f[B]\[dq]\f[R] commands are guaranteed to \f[B]NOT\f[R] be cryptographically secure. This is a consequence of using a seeded pseudo-random number generator. However, they \f[I]are\f[R] guaranteed to be reproducible with identical @@ -311,272 +342,340 @@ To deactivate them, just assign a different value to \f[B]obase\f[R]. .PP Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]$\f[R] -The top value is popped off the stack and copied, and the copy is -truncated and pushed onto the stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top value is popped off the stack and copied, and the copy is +truncated and pushed onto the stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The top two values are popped off the stack, and the precision of the +.PP +: The top two values are popped off the stack, and the precision of the second is set to the value of the first, whether by truncation or extension. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]H\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted left (radix shifted right) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]h\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted right (radix shifted left) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Pseudo-Random Number Generator .PP dc(1) has a built-in pseudo-random number generator. @@ -586,20 +685,24 @@ controls the pseudo-random number generator.) .PP The pseudo-random number generator is guaranteed to \f[B]NOT\f[R] be cryptographically secure. -.TP -\f[B]\[cq]\f[R] -Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive (see -the \f[B]LIMITS\f[R] section). -.RS .PP +\f[B]\[aq]\f[R] +.PP +: Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive +(see the \f[B]LIMITS\f[R] section). +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[dq]\f[R] -Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] +.PP +: Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] upper bound on the integer that will be generated. If the bound is negative or is a non-integer, an error is raised, and dc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] @@ -614,48 +717,58 @@ Using this command will change the value of \f[B]seed\f[R], unless the operand is \f[B]0\f[R] or \f[B]1\f[R]. In that case, \f[B]0\f[R] is pushed onto the stack, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.RS -.PP +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -664,113 +777,137 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and \f[B]seed\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]0\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section and the \f[B]NUMBERS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set -\f[B]scale\f[R], which must be non-negative. -.RS .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP +: Pops the value off of the top of the stack and uses it to set +\f[B]scale\f[R], which must be non-negative. +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi +.PP \f[B]j\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]seed\f[R]. The meaning of \f[B]seed\f[R] is dependent on the current pseudo-random number generator but is guaranteed to not change except for new major versions. -.RS +.IP +.nf +\f[C] +The *scale* and sign of the value may be significant. + +If a previously used **seed** value is used again, the pseudo-random number +generator is guaranteed to produce the same sequence of pseudo-random +numbers as it did when the **seed** value was previously used. + +The exact value assigned to **seed** is not guaranteed to be returned if the +**J** command is used. However, if **seed** *does* return a different value, +both values, when assigned to **seed**, are guaranteed to produce the same +sequence of pseudo-random numbers. This means that certain values assigned +to **seed** will not produce unique sequences of pseudo-random numbers. + +There is no limit to the length (number of significant decimal digits) or +*scale* of the value that can be assigned to **seed**. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The \f[I]scale\f[R] and sign of the value may be significant. -.PP -If a previously used \f[B]seed\f[R] value is used again, the -pseudo-random number generator is guaranteed to produce the same -sequence of pseudo-random numbers as it did when the \f[B]seed\f[R] -value was previously used. -.PP -The exact value assigned to \f[B]seed\f[R] is not guaranteed to be -returned if the \f[B]J\f[R] command is used. -However, if \f[B]seed\f[R] \f[I]does\f[R] return a different value, both -values, when assigned to \f[B]seed\f[R], are guaranteed to produce the -same sequence of pseudo-random numbers. -This means that certain values assigned to \f[B]seed\f[R] will not -produce unique sequences of pseudo-random numbers. -.PP -There is no limit to the length (number of significant decimal digits) -or \f[I]scale\f[R] of the value that can be assigned to \f[B]seed\f[R]. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]J\f[R] -Pushes the current value of \f[B]seed\f[R] onto the main stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the current value of \f[B]seed\f[R] onto the main stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +.PP +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]W\f[R] -Pushes the maximum (inclusive) integer that can be generated with the -\f[B]\[cq]\f[R] pseudo-random number generator command. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum (inclusive) integer that can be generated with the +\f[B]\[aq]\f[R] pseudo-random number generator command. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -787,233 +924,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -1028,8 +1224,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -1040,7 +1236,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -1085,64 +1281,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command, -if dc(1). +.PP +: The maximum integer (inclusive) returned by the \f[B]\[aq]\f[R] +command, if dc(1). Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -1152,104 +1361,117 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**H**), and right shift (**h**) +operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]H\f[R]), and right shift (\f[B]h\f[R]) operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1277,7 +1499,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1299,7 +1521,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/N.1.md b/manuals/dc/N.1.md index 43876cfb24a6..d790c960b5c7 100644 --- a/manuals/dc/N.1.md +++ b/manuals/dc/N.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -81,12 +81,26 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** : Disables the prompt in TTY mode. (The prompt is only enabled in TTY mode. - See the **TTY MODE** section) This is mostly for those users that do not + See the **TTY MODE** section.) This is mostly for those users that do not want a prompt or are not used to having them in dc(1). Most of those users would want to put this option in **DC_ENV_ARGS**. This is a **non-portable extension**. +**-R**, **-\-no-read-prompt** + +: Disables the read prompt in TTY mode. (The read prompt is only enabled in + TTY mode. See the **TTY MODE** section.) This is mostly for those users that + do not want a read prompt or are not used to having them in dc(1). Most of + those users would want to put this option in **BC_ENV_ARGS** (see the + **ENVIRONMENT VARIABLES** section). This option is also useful in hash bang + lines of dc(1) scripts that prompt for user input. + + This option does not disable the regular prompt because the read prompt is + only used when the **?** command is used. + + This is a **non-portable extension**. + **-x** **-\-extended-register** : Enables extended register mode. See the *Extended Register Mode* subsection @@ -556,25 +570,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -723,7 +737,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -735,7 +749,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -744,7 +758,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -753,7 +767,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -762,7 +776,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -771,7 +785,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -780,7 +794,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -789,7 +803,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -798,7 +812,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -807,7 +821,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -816,7 +830,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -825,7 +839,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -881,12 +895,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/NP.1 b/manuals/dc/NP.1 index ad4a69957c1c..75a56bbe3538 100644 --- a/manuals/dc/NP.1 +++ b/manuals/dc/NP.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,79 +70,100 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP +.PP +: Print the version information (copyright header) and exit. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -185,7 +206,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -195,7 +216,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -231,13 +252,13 @@ Likewise, when a value is assigned to \f[B]seed\f[R], it is not guaranteed that querying \f[B]seed\f[R] immediately after will return the same value. In addition, the value of \f[B]seed\f[R] will change after any call to -the \f[B]\[cq]\f[R] command or the \f[B]\[dq]\f[R] command that does not +the \f[B]\[aq]\f[R] command or the \f[B]\[dq]\f[R] command that does not get receive a value of \f[B]0\f[R] or \f[B]1\f[R]. -The maximum integer returned by the \f[B]\[cq]\f[R] command can be +The maximum integer returned by the \f[B]\[aq]\f[R] command can be queried with the \f[B]W\f[R] command. .PP \f[B]Note\f[R]: The values returned by the pseudo-random number -generator with the \f[B]\[cq]\f[R] and \f[B]\[dq]\f[R] commands are +generator with the \f[B]\[aq]\f[R] and \f[B]\[dq]\f[R] commands are guaranteed to \f[B]NOT\f[R] be cryptographically secure. This is a consequence of using a seeded pseudo-random number generator. However, they \f[I]are\f[R] guaranteed to be reproducible with identical @@ -306,272 +327,340 @@ To deactivate them, just assign a different value to \f[B]obase\f[R]. .PP Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]$\f[R] -The top value is popped off the stack and copied, and the copy is -truncated and pushed onto the stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top value is popped off the stack and copied, and the copy is +truncated and pushed onto the stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The top two values are popped off the stack, and the precision of the +.PP +: The top two values are popped off the stack, and the precision of the second is set to the value of the first, whether by truncation or extension. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]H\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted left (radix shifted right) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]h\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted right (radix shifted left) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Pseudo-Random Number Generator .PP dc(1) has a built-in pseudo-random number generator. @@ -581,20 +670,24 @@ controls the pseudo-random number generator.) .PP The pseudo-random number generator is guaranteed to \f[B]NOT\f[R] be cryptographically secure. -.TP -\f[B]\[cq]\f[R] -Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive (see -the \f[B]LIMITS\f[R] section). -.RS .PP +\f[B]\[aq]\f[R] +.PP +: Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive +(see the \f[B]LIMITS\f[R] section). +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[dq]\f[R] -Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] +.PP +: Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] upper bound on the integer that will be generated. If the bound is negative or is a non-integer, an error is raised, and dc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] @@ -609,48 +702,58 @@ Using this command will change the value of \f[B]seed\f[R], unless the operand is \f[B]0\f[R] or \f[B]1\f[R]. In that case, \f[B]0\f[R] is pushed onto the stack, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.RS -.PP +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -659,113 +762,137 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and \f[B]seed\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]0\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section and the \f[B]NUMBERS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set -\f[B]scale\f[R], which must be non-negative. -.RS .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP +: Pops the value off of the top of the stack and uses it to set +\f[B]scale\f[R], which must be non-negative. +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi +.PP \f[B]j\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]seed\f[R]. The meaning of \f[B]seed\f[R] is dependent on the current pseudo-random number generator but is guaranteed to not change except for new major versions. -.RS +.IP +.nf +\f[C] +The *scale* and sign of the value may be significant. + +If a previously used **seed** value is used again, the pseudo-random number +generator is guaranteed to produce the same sequence of pseudo-random +numbers as it did when the **seed** value was previously used. + +The exact value assigned to **seed** is not guaranteed to be returned if the +**J** command is used. However, if **seed** *does* return a different value, +both values, when assigned to **seed**, are guaranteed to produce the same +sequence of pseudo-random numbers. This means that certain values assigned +to **seed** will not produce unique sequences of pseudo-random numbers. + +There is no limit to the length (number of significant decimal digits) or +*scale* of the value that can be assigned to **seed**. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The \f[I]scale\f[R] and sign of the value may be significant. -.PP -If a previously used \f[B]seed\f[R] value is used again, the -pseudo-random number generator is guaranteed to produce the same -sequence of pseudo-random numbers as it did when the \f[B]seed\f[R] -value was previously used. -.PP -The exact value assigned to \f[B]seed\f[R] is not guaranteed to be -returned if the \f[B]J\f[R] command is used. -However, if \f[B]seed\f[R] \f[I]does\f[R] return a different value, both -values, when assigned to \f[B]seed\f[R], are guaranteed to produce the -same sequence of pseudo-random numbers. -This means that certain values assigned to \f[B]seed\f[R] will not -produce unique sequences of pseudo-random numbers. -.PP -There is no limit to the length (number of significant decimal digits) -or \f[I]scale\f[R] of the value that can be assigned to \f[B]seed\f[R]. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]J\f[R] -Pushes the current value of \f[B]seed\f[R] onto the main stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the current value of \f[B]seed\f[R] onto the main stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +.PP +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]W\f[R] -Pushes the maximum (inclusive) integer that can be generated with the -\f[B]\[cq]\f[R] pseudo-random number generator command. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum (inclusive) integer that can be generated with the +\f[B]\[aq]\f[R] pseudo-random number generator command. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -782,233 +909,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -1023,8 +1209,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -1035,7 +1221,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -1080,64 +1266,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command, -if dc(1). +.PP +: The maximum integer (inclusive) returned by the \f[B]\[aq]\f[R] +command, if dc(1). Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -1147,104 +1346,117 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**H**), and right shift (**h**) +operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]H\f[R]), and right shift (\f[B]h\f[R]) operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1272,7 +1484,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1292,7 +1504,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/NP.1.md b/manuals/dc/NP.1.md index b1f29d76f06e..4533a534e84c 100644 --- a/manuals/dc/NP.1.md +++ b/manuals/dc/NP.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -80,6 +80,12 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** +: This option is a no-op. + + This is a **non-portable extension**. + +**-R**, **-\-no-read-prompt** + : This option is a no-op. This is a **non-portable extension**. @@ -553,25 +559,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -720,7 +726,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -732,7 +738,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -741,7 +747,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -750,7 +756,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -759,7 +765,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -768,7 +774,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -777,7 +783,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -786,7 +792,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -795,7 +801,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -804,7 +810,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -813,7 +819,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -822,7 +828,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -878,12 +884,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/dc/P.1 b/manuals/dc/P.1 index 2bbe54c37604..6ee6d0f7bd2f 100644 --- a/manuals/dc/P.1 +++ b/manuals/dc/P.1 @@ -25,18 +25,18 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" .SH Name .PP dc - arbitrary-precision decimal reverse-Polish notation calculator .SH SYNOPSIS .PP -\f[B]dc\f[R] [\f[B]-hiPvVx\f[R]] [\f[B]--version\f[R]] +\f[B]dc\f[R] [\f[B]-hiPRvVx\f[R]] [\f[B]--version\f[R]] [\f[B]--help\f[R]] [\f[B]--interactive\f[R]] [\f[B]--no-prompt\f[R]] -[\f[B]--extended-register\f[R]] [\f[B]-e\f[R] \f[I]expr\f[R]] -[\f[B]--expression\f[R]=\f[I]expr\f[R]\&...] [\f[B]-f\f[R] -\f[I]file\f[R]\&...] [\f[B]--file\f[R]=\f[I]file\f[R]\&...] -[\f[I]file\f[R]\&...] +[\f[B]--no-read-prompt\f[R]] [\f[B]--extended-register\f[R]] +[\f[B]-e\f[R] \f[I]expr\f[R]] [\f[B]--expression\f[R]=\f[I]expr\f[R]...] +[\f[B]-f\f[R] \f[I]file\f[R]...] [\f[B]--file\f[R]=\f[I]file\f[R]...] +[\f[I]file\f[R]...] .SH DESCRIPTION .PP dc(1) is an arbitrary-precision calculator. @@ -70,79 +70,100 @@ argument or define the environment variable \f[B]DC_EXPR_EXIT\f[R]. .SH OPTIONS .PP The following are the options that dc(1) accepts. -.TP +.PP \f[B]-h\f[R], \f[B]--help\f[R] -Prints a usage message and quits. -.TP +.PP +: Prints a usage message and quits. +.PP \f[B]-v\f[R], \f[B]-V\f[R], \f[B]--version\f[R] -Print the version information (copyright header) and exit. -.TP +.PP +: Print the version information (copyright header) and exit. +.PP \f[B]-i\f[R], \f[B]--interactive\f[R] -Forces interactive mode. +.PP +: Forces interactive mode. (See the \f[B]INTERACTIVE MODE\f[R] section.) -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-P\f[R], \f[B]--no-prompt\f[R] -This option is a no-op. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]-R\f[R], \f[B]--no-read-prompt\f[R] +.PP +: This option is a no-op. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]-x\f[R] \f[B]--extended-register\f[R] -Enables extended register mode. +.PP +: Enables extended register mode. See the \f[I]Extended Register Mode\f[R] subsection of the \f[B]REGISTERS\f[R] section for more information. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-e\f[R] \f[I]expr\f[R], \f[B]--expression\f[R]=\f[I]expr\f[R] -Evaluates \f[I]expr\f[R]. +.PP +: Evaluates \f[I]expr\f[R]. If multiple expressions are given, they are evaluated in order. If files are given as well (see below), the expressions and files are evaluated in the order given. This means that if a file is given before an expression, the file is read in and evaluated first. -.RS +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**, whether on the +command-line or in **DC_ENV_ARGS**. However, if any other **-e**, +**-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after **-f-** +or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R], whether on the command-line or in -\f[B]DC_ENV_ARGS\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]-f\f[R] \f[I]file\f[R], \f[B]--file\f[R]=\f[I]file\f[R] -Reads in \f[I]file\f[R] and evaluates it, line by line, as though it +.PP +: Reads in \f[I]file\f[R] and evaluates it, line by line, as though it were read through \f[B]stdin\f[R]. If expressions are also given (see above), the expressions are evaluated in the order given. -.RS -.PP -If this option is given on the command-line (i.e., not in -\f[B]DC_ENV_ARGS\f[R], see the \f[B]ENVIRONMENT VARIABLES\f[R] section), -then after processing all expressions and files, dc(1) will exit, unless -\f[B]-\f[R] (\f[B]stdin\f[R]) was given as an argument at least once to -\f[B]-f\f[R] or \f[B]--file\f[R]. -However, if any other \f[B]-e\f[R], \f[B]--expression\f[R], -\f[B]-f\f[R], or \f[B]--file\f[R] arguments are given after -\f[B]-f-\f[R] or equivalent is given, dc(1) will give a fatal error and -exit. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +If this option is given on the command-line (i.e., not in **DC_ENV_ARGS**, +see the **ENVIRONMENT VARIABLES** section), then after processing all +expressions and files, dc(1) will exit, unless **-** (**stdin**) was given +as an argument at least once to **-f** or **-\[rs]-file**. However, if any other +**-e**, **-\[rs]-expression**, **-f**, or **-\[rs]-file** arguments are given after +**-f-** or equivalent is given, dc(1) will give a fatal error and exit. + +This is a **non-portable extension**. +\f[R] +.fi .PP All long options are \f[B]non-portable extensions\f[R]. .SH STDOUT @@ -185,7 +206,7 @@ Input is processed immediately when entered. .PP \f[B]ibase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to interpret constant numbers. -It is the \[lq]input\[rq] base, or the number base used for interpreting +It is the \[dq]input\[dq] base, or the number base used for interpreting input numbers. \f[B]ibase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]ibase\f[R] is \f[B]16\f[R]. @@ -195,7 +216,7 @@ programs with the \f[B]T\f[R] command. .PP \f[B]obase\f[R] is a register (see the \f[B]REGISTERS\f[R] section) that determines how to output results. -It is the \[lq]output\[rq] base, or the number base used for outputting +It is the \[dq]output\[dq] base, or the number base used for outputting numbers. \f[B]obase\f[R] is initially \f[B]10\f[R]. The max allowable value for \f[B]obase\f[R] is \f[B]DC_BASE_MAX\f[R] and @@ -231,13 +252,13 @@ Likewise, when a value is assigned to \f[B]seed\f[R], it is not guaranteed that querying \f[B]seed\f[R] immediately after will return the same value. In addition, the value of \f[B]seed\f[R] will change after any call to -the \f[B]\[cq]\f[R] command or the \f[B]\[dq]\f[R] command that does not +the \f[B]\[aq]\f[R] command or the \f[B]\[dq]\f[R] command that does not get receive a value of \f[B]0\f[R] or \f[B]1\f[R]. -The maximum integer returned by the \f[B]\[cq]\f[R] command can be +The maximum integer returned by the \f[B]\[aq]\f[R] command can be queried with the \f[B]W\f[R] command. .PP \f[B]Note\f[R]: The values returned by the pseudo-random number -generator with the \f[B]\[cq]\f[R] and \f[B]\[dq]\f[R] commands are +generator with the \f[B]\[aq]\f[R] and \f[B]\[dq]\f[R] commands are guaranteed to \f[B]NOT\f[R] be cryptographically secure. This is a consequence of using a seeded pseudo-random number generator. However, they \f[I]are\f[R] guaranteed to be reproducible with identical @@ -306,272 +327,340 @@ To deactivate them, just assign a different value to \f[B]obase\f[R]. .PP Printing numbers in scientific notation and/or engineering notation is a \f[B]non-portable extension\f[R]. -.TP +.PP \f[B]p\f[R] -Prints the value on top of the stack, whether number or string, and +.PP +: Prints the value on top of the stack, whether number or string, and prints a newline after. -.RS -.PP +.IP +.nf +\f[C] This does not alter the stack. -.RE -.TP +\f[R] +.fi +.PP \f[B]n\f[R] -Prints the value on top of the stack, whether number or string, and pops -it off of the stack. -.TP +.PP +: Prints the value on top of the stack, whether number or string, and +pops it off of the stack. +.PP \f[B]P\f[R] -Pops a value off the stack. -.RS .PP +: Pops a value off the stack. +.IP +.nf +\f[C] If the value is a number, it is truncated and the absolute value of the -result is printed as though \f[B]obase\f[R] is \f[B]UCHAR_MAX+1\f[R] and -each digit is interpreted as an ASCII character, making it a byte -stream. -.PP +result is printed as though **obase** is **UCHAR_MAX+1** and each digit is +interpreted as an ASCII character, making it a byte stream. + If the value is a string, it is printed without a trailing newline. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]f\f[R] -Prints the entire contents of the stack, in order from newest to oldest, -without altering anything. -.RS .PP +: Prints the entire contents of the stack, in order from newest to +oldest, without altering anything. +.IP +.nf +\f[C] Users should use this command when they get lost. -.RE +\f[R] +.fi .SS Arithmetic .PP These are the commands used for arithmetic. -.TP +.PP \f[B]+\f[R] -The top two values are popped off the stack, added, and the result is +.PP +: The top two values are popped off the stack, added, and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]-\f[R] -The top two values are popped off the stack, subtracted, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, subtracted, and the +result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to the max \f[I]scale\f[R] of both operands. -.TP +.PP \f[B]*\f[R] -The top two values are popped off the stack, multiplied, and the result -is pushed onto the stack. +.PP +: The top two values are popped off the stack, multiplied, and the +result is pushed onto the stack. If \f[B]a\f[R] is the \f[I]scale\f[R] of the first expression and \f[B]b\f[R] is the \f[I]scale\f[R] of the second expression, the \f[I]scale\f[R] of the result is equal to \f[B]min(a+b,max(scale,a,b))\f[R] where \f[B]min()\f[R] and \f[B]max()\f[R] return the obvious values. -.TP +.PP \f[B]/\f[R] -The top two values are popped off the stack, divided, and the result is -pushed onto the stack. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP -The first value popped off of the stack must be non-zero. -.RE -.TP -\f[B]%\f[R] -The top two values are popped off the stack, remaindered, and the result +: The top two values are popped off the stack, divided, and the result is pushed onto the stack. -.RS -.PP -Remaindering is equivalent to 1) Computing \f[B]a/b\f[R] to current -\f[B]scale\f[R], and 2) Using the result of step 1 to calculate -\f[B]a-(a/b)*b\f[R] to \f[I]scale\f[R] -\f[B]max(scale+scale(b),scale(a))\f[R]. -.PP +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. -.RE -.TP +\f[R] +.fi +.PP +\f[B]%\f[R] +.PP +: The top two values are popped off the stack, remaindered, and the +result is pushed onto the stack. +.IP +.nf +\f[C] +Remaindering is equivalent to 1) Computing **a/b** to current **scale**, and +2) Using the result of step 1 to calculate **a-(a/b)\[rs]*b** to *scale* +**max(scale+scale(b),scale(a))**. + +The first value popped off of the stack must be non-zero. +\f[R] +.fi +.PP \f[B]\[ti]\f[R] -The top two values are popped off the stack, divided and remaindered, +.PP +: The top two values are popped off the stack, divided and remaindered, and the results (divided first, remainder second) are pushed onto the stack. This is equivalent to \f[B]x y / x y %\f[R] except that \f[B]x\f[R] and \f[B]y\f[R] are only evaluated once. -.RS -.PP +.IP +.nf +\f[C] The first value popped off of the stack must be non-zero. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[ha]\f[R] -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. -The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS .PP +: 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. +The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. +.IP +.nf +\f[C] 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 non-zero. -.RE -.TP +\f[R] +.fi +.PP \f[B]v\f[R] -The top value is popped off the stack, its square root is computed, and -the result is pushed onto the stack. +.PP +: The top value is popped off the stack, its square root is computed, +and the result is pushed onto the stack. The \f[I]scale\f[R] of the result is equal to \f[B]scale\f[R]. -.RS -.PP +.IP +.nf +\f[C] The value popped off of the stack must be non-negative. -.RE -.TP -\f[B]_\f[R] -If this command \f[I]immediately\f[R] precedes a number (i.e., no spaces -or other commands), then that number is input as a negative number. -.RS +\f[R] +.fi +.PP +\f[B]_\f[R] +.PP +: If this command \f[I]immediately\f[R] precedes a number (i.e., no +spaces or other commands), then that number is input as a negative +number. +.IP +.nf +\f[C] +Otherwise, the top value on the stack is popped and copied, and the copy is +negated and pushed onto the stack. This behavior without a number is a +**non-portable extension**. +\f[R] +.fi .PP -Otherwise, the top value on the stack is popped and copied, and the copy -is negated and pushed onto the stack. -This behavior without a number is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]b\f[R] -The top value is popped off the stack, and if it is zero, it is pushed +.PP +: The top value is popped off the stack, and if it is zero, it is pushed back onto the stack. Otherwise, its absolute value is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]|\f[R] -The top three values are popped off the stack, a modular exponentiation -is computed, and the result is pushed onto the stack. -.RS .PP +: The top three values are popped off the stack, a modular +exponentiation is computed, and the result is pushed onto the stack. +.IP +.nf +\f[C] The first value popped is used as the reduction modulus and must be an -integer and non-zero. -The second value popped is used as the exponent and must be an integer -and non-negative. -The third value popped is the base and must be an integer. +integer and non-zero. The second value popped is used as the exponent and +must be an integer and non-negative. The third value popped is the base and +must be an integer. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]$\f[R] -The top value is popped off the stack and copied, and the copy is -truncated and pushed onto the stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top value is popped off the stack and copied, and the copy is +truncated and pushed onto the stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]\[at]\f[R] -The top two values are popped off the stack, and the precision of the +.PP +: The top two values are popped off the stack, and the precision of the second is set to the value of the first, whether by truncation or extension. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]H\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted left (radix shifted right) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]h\f[R] -The top two values are popped off the stack, and the second is shifted +.PP +: The top two values are popped off the stack, and the second is shifted right (radix shifted left) to the value of the first. -.RS +.IP +.nf +\f[C] +The first value popped off of the stack must be an integer and non-negative. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The first value popped off of the stack must be an integer and -non-negative. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]G\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if they are equal, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]N\f[R] -The top value is popped off of the stack, and if it a \f[B]0\f[R], a +.PP +: The top value is popped off of the stack, and if it a \f[B]0\f[R], a \f[B]1\f[R] is pushed; otherwise, a \f[B]0\f[R] is pushed. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B](\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than the second, or -\f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]{\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is less than or equal to the second, -or \f[B]0\f[R] otherwise. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B])\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than the second, or -\f[B]0\f[R] otherwise. -.RS -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP -\f[B]}\f[R] -The top two values are popped off of the stack, they are compared, and a -\f[B]1\f[R] is pushed if the first is greater than or equal to the +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is less than or equal to the second, or \f[B]0\f[R] otherwise. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B])\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than the second, or +\f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP +\f[B]}\f[R] +.PP +: The top two values are popped off of the stack, they are compared, and +a \f[B]1\f[R] is pushed if the first is greater than or equal to the +second, or \f[B]0\f[R] otherwise. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]M\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If they are both non-zero, a \f[B]1\f[R] is pushed onto the stack. If either of them is zero, or both of them are, then a \f[B]0\f[R] is pushed onto the stack. -.RS +.IP +.nf +\f[C] +This is like the **&&** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is like the \f[B]&&\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]m\f[R] -The top two values are popped off of the stack. +.PP +: The top two values are popped off of the stack. If at least one of them is non-zero, a \f[B]1\f[R] is pushed onto the stack. If both of them are zero, then a \f[B]0\f[R] is pushed onto the stack. -.RS -.PP -This is like the \f[B]||\f[R] operator in bc(1), and it is \f[I]not\f[R] -a short-circuit operator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE +.IP +.nf +\f[C] +This is like the **||** operator in bc(1), and it is *not* a short-circuit +operator. + +This is a **non-portable extension**. +\f[R] +.fi .SS Pseudo-Random Number Generator .PP dc(1) has a built-in pseudo-random number generator. @@ -581,20 +670,24 @@ controls the pseudo-random number generator.) .PP The pseudo-random number generator is guaranteed to \f[B]NOT\f[R] be cryptographically secure. -.TP -\f[B]\[cq]\f[R] -Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive (see -the \f[B]LIMITS\f[R] section). -.RS .PP +\f[B]\[aq]\f[R] +.PP +: Generates an integer between 0 and \f[B]DC_RAND_MAX\f[R], inclusive +(see the \f[B]LIMITS\f[R] section). +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]\[dq]\f[R] -Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] +.PP +: Pops a value off of the stack, which is used as an \f[B]exclusive\f[R] upper bound on the integer that will be generated. If the bound is negative or is a non-integer, an error is raised, and dc(1) resets (see the \f[B]RESET\f[R] section) while \f[B]seed\f[R] @@ -609,48 +702,58 @@ Using this command will change the value of \f[B]seed\f[R], unless the operand is \f[B]0\f[R] or \f[B]1\f[R]. In that case, \f[B]0\f[R] is pushed onto the stack, and \f[B]seed\f[R] is \f[I]not\f[R] changed. -.RS -.PP +.IP +.nf +\f[C] The generated integer is made as unbiased as possible, subject to the limitations of the pseudo-random number generator. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE + +This is a **non-portable extension**. +\f[R] +.fi .SS Stack Control .PP These commands control the stack. -.TP +.PP \f[B]c\f[R] -Removes all items from (\[lq]clears\[rq]) the stack. -.TP +.PP +: Removes all items from (\[dq]clears\[dq]) the stack. +.PP \f[B]d\f[R] -Copies the item on top of the stack (\[lq]duplicates\[rq]) and pushes +.PP +: Copies the item on top of the stack (\[dq]duplicates\[dq]) and pushes the copy onto the stack. -.TP +.PP \f[B]r\f[R] -Swaps (\[lq]reverses\[rq]) the two top items on the stack. -.TP +.PP +: Swaps (\[dq]reverses\[dq]) the two top items on the stack. +.PP \f[B]R\f[R] -Pops (\[lq]removes\[rq]) the top value from the stack. +.PP +: Pops (\[dq]removes\[dq]) the top value from the stack. .SS Register Control .PP These commands control registers (see the \f[B]REGISTERS\f[R] section). -.TP +.PP \f[B]s\f[R]\f[I]r\f[R] -Pops the value off the top of the stack and stores it into register +.PP +: Pops the value off the top of the stack and stores it into register \f[I]r\f[R]. -.TP +.PP \f[B]l\f[R]\f[I]r\f[R] -Copies the value in register \f[I]r\f[R] and pushes it onto the stack. +.PP +: Copies the value in register \f[I]r\f[R] and pushes it onto the stack. This does not alter the contents of \f[I]r\f[R]. -.TP +.PP \f[B]S\f[R]\f[I]r\f[R] -Pops the value off the top of the (main) stack and pushes it onto the +.PP +: Pops the value off the top of the (main) stack and pushes it onto the stack of register \f[I]r\f[R]. The previous value of the register becomes inaccessible. -.TP +.PP \f[B]L\f[R]\f[I]r\f[R] -Pops the value off the top of the stack for register \f[I]r\f[R] and +.PP +: Pops the value off the top of the stack for register \f[I]r\f[R] and push it onto the main stack. The previous value in the stack for register \f[I]r\f[R], if any, is now accessible via the \f[B]l\f[R]\f[I]r\f[R] command. @@ -659,113 +762,137 @@ accessible via the \f[B]l\f[R]\f[I]r\f[R] command. These commands control the values of \f[B]ibase\f[R], \f[B]obase\f[R], \f[B]scale\f[R], and \f[B]seed\f[R]. Also see the \f[B]SYNTAX\f[R] section. -.TP +.PP \f[B]i\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]ibase\f[R], which must be between \f[B]2\f[R] and \f[B]16\f[R], inclusive. -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]o\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]obase\f[R], which must be between \f[B]0\f[R] and \f[B]DC_BASE_MAX\f[R], inclusive (see the \f[B]LIMITS\f[R] section and the \f[B]NUMBERS\f[R] section). -.RS +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP \f[B]k\f[R] -Pops the value off of the top of the stack and uses it to set -\f[B]scale\f[R], which must be non-negative. -.RS .PP -If the value on top of the stack has any \f[I]scale\f[R], the -\f[I]scale\f[R] is ignored. -.RE -.TP +: Pops the value off of the top of the stack and uses it to set +\f[B]scale\f[R], which must be non-negative. +.IP +.nf +\f[C] +If the value on top of the stack has any *scale*, the *scale* is ignored. +\f[R] +.fi +.PP \f[B]j\f[R] -Pops the value off of the top of the stack and uses it to set +.PP +: Pops the value off of the top of the stack and uses it to set \f[B]seed\f[R]. The meaning of \f[B]seed\f[R] is dependent on the current pseudo-random number generator but is guaranteed to not change except for new major versions. -.RS +.IP +.nf +\f[C] +The *scale* and sign of the value may be significant. + +If a previously used **seed** value is used again, the pseudo-random number +generator is guaranteed to produce the same sequence of pseudo-random +numbers as it did when the **seed** value was previously used. + +The exact value assigned to **seed** is not guaranteed to be returned if the +**J** command is used. However, if **seed** *does* return a different value, +both values, when assigned to **seed**, are guaranteed to produce the same +sequence of pseudo-random numbers. This means that certain values assigned +to **seed** will not produce unique sequences of pseudo-random numbers. + +There is no limit to the length (number of significant decimal digits) or +*scale* of the value that can be assigned to **seed**. + +This is a **non-portable extension**. +\f[R] +.fi .PP -The \f[I]scale\f[R] and sign of the value may be significant. -.PP -If a previously used \f[B]seed\f[R] value is used again, the -pseudo-random number generator is guaranteed to produce the same -sequence of pseudo-random numbers as it did when the \f[B]seed\f[R] -value was previously used. -.PP -The exact value assigned to \f[B]seed\f[R] is not guaranteed to be -returned if the \f[B]J\f[R] command is used. -However, if \f[B]seed\f[R] \f[I]does\f[R] return a different value, both -values, when assigned to \f[B]seed\f[R], are guaranteed to produce the -same sequence of pseudo-random numbers. -This means that certain values assigned to \f[B]seed\f[R] will not -produce unique sequences of pseudo-random numbers. -.PP -There is no limit to the length (number of significant decimal digits) -or \f[I]scale\f[R] of the value that can be assigned to \f[B]seed\f[R]. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]I\f[R] -Pushes the current value of \f[B]ibase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]ibase\f[R] onto the main stack. +.PP \f[B]O\f[R] -Pushes the current value of \f[B]obase\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]obase\f[R] onto the main stack. +.PP \f[B]K\f[R] -Pushes the current value of \f[B]scale\f[R] onto the main stack. -.TP +.PP +: Pushes the current value of \f[B]scale\f[R] onto the main stack. +.PP \f[B]J\f[R] -Pushes the current value of \f[B]seed\f[R] onto the main stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the current value of \f[B]seed\f[R] onto the main stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]T\f[R] -Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]ibase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]U\f[R] -Pushes the maximum allowable value of \f[B]obase\f[R] onto the main -stack. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP +: Pushes the maximum allowable value of \f[B]obase\f[R] onto the main +stack. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi +.PP \f[B]V\f[R] -Pushes the maximum allowable value of \f[B]scale\f[R] onto the main +.PP +: Pushes the maximum allowable value of \f[B]scale\f[R] onto the main stack. -.RS +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]W\f[R] -Pushes the maximum (inclusive) integer that can be generated with the -\f[B]\[cq]\f[R] pseudo-random number generator command. -.RS .PP -This is a \f[B]non-portable extension\f[R]. -.RE +: Pushes the maximum (inclusive) integer that can be generated with the +\f[B]\[aq]\f[R] pseudo-random number generator command. +.IP +.nf +\f[C] +This is a **non-portable extension**. +\f[R] +.fi .SS Strings .PP The following commands control strings. @@ -782,233 +909,292 @@ Strings can also be executed as macros. For example, if the string \f[B][1pR]\f[R] is executed as a macro, then the code \f[B]1pR\f[R] is executed, meaning that the \f[B]1\f[R] will be printed with a newline after and then popped from the stack. -.TP -\f[B][\f[R]_characters_\f[B]]\f[R] -Makes a string containing \f[I]characters\f[R] and pushes it onto the +.PP +\f[B][\f[R]\f[I]characters\f[R]\f[B]]\f[R] +.PP +: Makes a string containing \f[I]characters\f[R] and pushes it onto the stack. -.RS -.PP -If there are brackets (\f[B][\f[R] and \f[B]]\f[R]) in the string, then -they must be balanced. -Unbalanced brackets can be escaped using a backslash (\f[B]\[rs]\f[R]) +.IP +.nf +\f[C] +If there are brackets (**\[rs][** and **\[rs]]**) in the string, then they must be +balanced. Unbalanced brackets can be escaped using a backslash (**\[rs]\[rs]**) character. -.PP + If there is a backslash character in the string, the character after it -(even another backslash) is put into the string verbatim, but the -(first) backslash is not. -.RE -.TP +(even another backslash) is put into the string verbatim, but the (first) +backslash is not. +\f[R] +.fi +.PP \f[B]a\f[R] -The value on top of the stack is popped. -.RS .PP -If it is a number, it is truncated and its absolute value is taken. -The result mod \f[B]UCHAR_MAX+1\f[R] is calculated. -If that result is \f[B]0\f[R], push an empty string; otherwise, push a -one-character string where the character is the result of the mod -interpreted as an ASCII character. +: The value on top of the stack is popped. +.IP +.nf +\f[C] +If it is a number, it is truncated and its absolute value is taken. The +result mod **UCHAR_MAX+1** is calculated. If that result is **0**, push an +empty string; otherwise, push a one-character string where the character is +the result of the mod interpreted as an ASCII character. + +If it is a string, then a new string is made. If the original string is +empty, the new string is empty. If it is not, then the first character of +the original string is used to create the new string as a one-character +string. The new string is then pushed onto the stack. + +This is a **non-portable extension**. +\f[R] +.fi .PP -If it is a string, then a new string is made. -If the original string is empty, the new string is empty. -If it is not, then the first character of the original string is used to -create the new string as a one-character string. -The new string is then pushed onto the stack. -.PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]x\f[R] -Pops a value off of the top of the stack. -.RS .PP +: Pops a value off of the top of the stack. +.IP +.nf +\f[C] If it is a number, it is pushed back onto the stack. -.PP + If it is a string, it is executed as a macro. -.PP + This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -.RE -.TP +\f[R] +.fi +.PP \f[B]>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is greater than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +For example, **0 1>a** will execute the contents of register **a**, and +**1 0>a** will not. + +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -For example, \f[B]0 1>a\f[R] will execute the contents of register -\f[B]a\f[R], and \f[B]1 0>a\f[R] will not. -.PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not greater than the second (less than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!>\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is less than the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not less than the second (greater than or equal to), then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!<\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R] -Pops two values off of the stack that must be numbers and compares them. +.PP +: Pops two values off of the stack that must be numbers and compares +them. If the first value is not equal to the second, then the contents of register \f[I]r\f[R] are executed. -.RS +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). +\f[R] +.fi .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). -.RE -.TP \f[B]!=\f[R]\f[I]r\f[R]\f[B]e\f[R]\f[I]s\f[R] -Like the above, but will execute register \f[I]s\f[R] if the comparison -fails. -.RS .PP -If either or both of the values are not numbers, dc(1) will raise an -error and reset (see the \f[B]RESET\f[R] section). +: Like the above, but will execute register \f[I]s\f[R] if the +comparison fails. +.IP +.nf +\f[C] +If either or both of the values are not numbers, dc(1) will raise an error +and reset (see the **RESET** section). + +This is a **non-portable extension**. +\f[R] +.fi .PP -This is a \f[B]non-portable extension\f[R]. -.RE -.TP \f[B]?\f[R] -Reads a line from the \f[B]stdin\f[R] and executes it. +.PP +: Reads a line from the \f[B]stdin\f[R] and executes it. This is to allow macros to request input from users. -.TP +.PP \f[B]q\f[R] -During execution of a macro, this exits the execution of that macro and -the execution of the macro that executed it. +.PP +: During execution of a macro, this exits the execution of that macro +and the execution of the macro that executed it. If there are no macros, or only one macro executing, dc(1) exits. -.TP +.PP \f[B]Q\f[R] -Pops a value from the stack which must be non-negative and is used the +.PP +: Pops a value from the stack which must be non-negative and is used the number of macro executions to pop off of the execution stack. If the number of levels to pop is greater than the number of executing macros, dc(1) exits. .SS Status .PP These commands query status of the stack or its top value. -.TP +.PP \f[B]Z\f[R] -Pops a value off of the stack. -.RS -.PP -If it is a number, calculates the number of significant decimal digits -it has and pushes the result. .PP +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, calculates the number of significant decimal digits it +has and pushes the result. + If it is a string, pushes the number of characters the string has. -.RE -.TP +\f[R] +.fi +.PP \f[B]X\f[R] -Pops a value off of the stack. -.RS .PP -If it is a number, pushes the \f[I]scale\f[R] of the value onto the -stack. +: Pops a value off of the stack. +.IP +.nf +\f[C] +If it is a number, pushes the *scale* of the value onto the stack. + +If it is a string, pushes **0**. +\f[R] +.fi .PP -If it is a string, pushes \f[B]0\f[R]. -.RE -.TP \f[B]z\f[R] -Pushes the current stack depth (before execution of this command). +.PP +: Pushes the current stack depth (before execution of this command). .SS Arrays .PP These commands manipulate arrays. -.TP +.PP \f[B]:\f[R]\f[I]r\f[R] -Pops the top two values off of the stack. +.PP +: Pops the top two values off of the stack. The second value will be stored in the array \f[I]r\f[R] (see the \f[B]REGISTERS\f[R] section), indexed by the first value. -.TP +.PP \f[B];\f[R]\f[I]r\f[R] -Pops the value on top of the stack and uses it as an index into the +.PP +: Pops the value on top of the stack and uses it as an index into the array \f[I]r\f[R]. The selected value is then pushed onto the stack. .SH REGISTERS @@ -1023,8 +1209,8 @@ their stack. .PP In non-extended register mode, a register name is just the single character that follows any command that needs a register name. -The only exception is a newline (\f[B]`\[rs]n'\f[R]); it is a parse -error for a newline to be used as a register name. +The only exception is a newline (\f[B]\[aq]\[rs]n\[aq]\f[R]); it is a +parse error for a newline to be used as a register name. .SS Extended Register Mode .PP Unlike most other dc(1) implentations, this dc(1) provides nearly @@ -1035,7 +1221,7 @@ If extended register mode is enabled (\f[B]-x\f[R] or normal single character registers are used \f[I]unless\f[R] the character immediately following a command that needs a register name is a space (according to \f[B]isspace()\f[R]) and not a newline -(\f[B]`\[rs]n'\f[R]). +(\f[B]\[aq]\[rs]n\[aq]\f[R]). .PP In that case, the register name is found according to the regex \f[B][a-z][a-z0-9_]*\f[R] (like bc(1) identifiers), and it is a parse @@ -1080,64 +1266,77 @@ always at least twice as large as the integer type used to store digits. .SH LIMITS .PP The following are the limits on dc(1): -.TP +.PP \f[B]DC_LONG_BIT\f[R] -The number of bits in the \f[B]long\f[R] type in the environment where +.PP +: The number of bits in the \f[B]long\f[R] type in the environment where dc(1) was built. This determines how many decimal digits can be stored in a single large integer (see the \f[B]PERFORMANCE\f[R] section). -.TP +.PP \f[B]DC_BASE_DIGS\f[R] -The number of decimal digits per large integer (see the +.PP +: The number of decimal digits per large integer (see the \f[B]PERFORMANCE\f[R] section). Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_POW\f[R] -The max decimal number that each large integer can store (see +.PP +: The max decimal number that each large integer can store (see \f[B]DC_BASE_DIGS\f[R]) plus \f[B]1\f[R]. Depends on \f[B]DC_BASE_DIGS\f[R]. -.TP +.PP \f[B]DC_OVERFLOW_MAX\f[R] -The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] +.PP +: The max number that the overflow type (see the \f[B]PERFORMANCE\f[R] section) can hold. Depends on \f[B]DC_LONG_BIT\f[R]. -.TP +.PP \f[B]DC_BASE_MAX\f[R] -The maximum output base. +.PP +: The maximum output base. Set at \f[B]DC_BASE_POW\f[R]. -.TP +.PP \f[B]DC_DIM_MAX\f[R] -The maximum size of arrays. +.PP +: The maximum size of arrays. Set at \f[B]SIZE_MAX-1\f[R]. -.TP +.PP \f[B]DC_SCALE_MAX\f[R] -The maximum \f[B]scale\f[R]. +.PP +: The maximum \f[B]scale\f[R]. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_STRING_MAX\f[R] -The maximum length of strings. +.PP +: The maximum length of strings. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NAME_MAX\f[R] -The maximum length of identifiers. +.PP +: The maximum length of identifiers. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_NUM_MAX\f[R] -The maximum length of a number (in decimal digits), which includes +.PP +: The maximum length of a number (in decimal digits), which includes digits after the decimal point. Set at \f[B]DC_OVERFLOW_MAX-1\f[R]. -.TP +.PP \f[B]DC_RAND_MAX\f[R] -The maximum integer (inclusive) returned by the \f[B]\[cq]\f[R] command, -if dc(1). +.PP +: The maximum integer (inclusive) returned by the \f[B]\[aq]\f[R] +command, if dc(1). Set at \f[B]2\[ha]DC_LONG_BIT-1\f[R]. -.TP +.PP Exponent -The maximum allowable exponent (positive or negative). +.PP +: The maximum allowable exponent (positive or negative). Set at \f[B]DC_OVERFLOW_MAX\f[R]. -.TP +.PP Number of vars -The maximum number of vars/arrays. +.PP +: The maximum number of vars/arrays. Set at \f[B]SIZE_MAX-1\f[R]. .PP These limits are meant to be effectively non-existent; the limits are so @@ -1147,104 +1346,117 @@ In fact, memory should be exhausted before these limits should be hit. .SH ENVIRONMENT VARIABLES .PP dc(1) recognizes the following environment variables: -.TP +.PP \f[B]DC_ENV_ARGS\f[R] -This is another way to give command-line arguments to dc(1). +.PP +: This is another way to give command-line arguments to dc(1). They should be in the same format as all other command-line arguments. These are always processed first, so any files given in \f[B]DC_ENV_ARGS\f[R] will be processed before arguments and files given on the command-line. -This gives the user the ability to set up \[lq]standard\[rq] options and +This gives the user the ability to set up \[dq]standard\[dq] options and files to be used at every invocation. The most useful thing for such files to contain would be useful functions that the user might want every time dc(1) runs. Another use would be to use the \f[B]-e\f[R] option to set \f[B]scale\f[R] to a value other than \f[B]0\f[R]. -.RS +.IP +.nf +\f[C] +The code that parses **DC_ENV_ARGS** will correctly handle quoted arguments, +but it does not understand escape sequences. For example, the string +**\[dq]/home/gavin/some dc file.dc\[dq]** will be correctly parsed, but the string +**\[dq]/home/gavin/some \[rs]\[dq]dc\[rs]\[dq] file.dc\[dq]** will include the backslashes. + +The quote parsing will handle either kind of quotes, **\[aq]** or **\[dq]**. Thus, +if you have a file with any number of single quotes in the name, you can use +double quotes as the outside quotes, as in **\[dq]some \[aq]dc\[aq] file.dc\[dq]**, and vice +versa if you have a file with double quotes. However, handling a file with +both kinds of quotes in **DC_ENV_ARGS** is not supported due to the +complexity of the parsing, though such files are still supported on the +command-line where the parsing is done by the shell. +\f[R] +.fi .PP -The code that parses \f[B]DC_ENV_ARGS\f[R] will correctly handle quoted -arguments, but it does not understand escape sequences. -For example, the string \f[B]\[lq]/home/gavin/some dc file.dc\[rq]\f[R] -will be correctly parsed, but the string \f[B]\[lq]/home/gavin/some -\[dq]dc\[dq] file.dc\[rq]\f[R] will include the backslashes. -.PP -The quote parsing will handle either kind of quotes, \f[B]\[cq]\f[R] or -\f[B]\[lq]\f[R]. Thus, if you have a file with any number of single -quotes in the name, you can use double quotes as the outside quotes, as -in \f[B]\[rq]some `dc' file.dc\[dq]\f[R], and vice versa if you have a -file with double quotes. -However, handling a file with both kinds of quotes in -\f[B]DC_ENV_ARGS\f[R] is not supported due to the complexity of the -parsing, though such files are still supported on the command-line where -the parsing is done by the shell. -.RE -.TP \f[B]DC_LINE_LENGTH\f[R] -If this environment variable exists and contains an integer that is +.PP +: If this environment variable exists and contains an integer that is greater than \f[B]1\f[R] and is less than \f[B]UINT16_MAX\f[R] (\f[B]2\[ha]16-1\f[R]), dc(1) will output lines to that length, including the backslash newline combo. The default line length is \f[B]70\f[R]. -.TP +.PP \f[B]DC_EXPR_EXIT\f[R] -If this variable exists (no matter the contents), dc(1) will exit +.PP +: If this variable exists (no matter the contents), dc(1) will exit immediately after executing expressions and files given by the \f[B]-e\f[R] and/or \f[B]-f\f[R] command-line options (and any equivalents). .SH EXIT STATUS .PP dc(1) returns the following exit statuses: -.TP +.PP \f[B]0\f[R] -No error. -.TP +.PP +: No error. +.PP \f[B]1\f[R] -A math error occurred. +.PP +: A math error occurred. This follows standard practice of using \f[B]1\f[R] for expected errors, since math errors will happen in the process of normal execution. -.RS +.IP +.nf +\f[C] +Math errors include divide by **0**, taking the square root of a negative +number, using a negative number as a bound for the pseudo-random number +generator, attempting to convert a negative number to a hardware integer, +overflow when converting a number to a hardware integer, and attempting to +use a non-integer where an integer is required. + +Converting to a hardware integer happens for the second operand of the power +(**\[rs]\[ha]**), places (**\[rs]\[at]**), left shift (**H**), and right shift (**h**) +operators. +\f[R] +.fi .PP -Math errors include divide by \f[B]0\f[R], taking the square root of a -negative number, using a negative number as a bound for the -pseudo-random number generator, attempting to convert a negative number -to a hardware integer, overflow when converting a number to a hardware -integer, and attempting to use a non-integer where an integer is -required. -.PP -Converting to a hardware integer happens for the second operand of the -power (\f[B]\[ha]\f[R]), places (\f[B]\[at]\f[R]), left shift -(\f[B]H\f[R]), and right shift (\f[B]h\f[R]) operators. -.RE -.TP \f[B]2\f[R] -A parse error occurred. -.RS .PP -Parse errors include unexpected \f[B]EOF\f[R], using an invalid -character, failing to find the end of a string or comment, and using a -token where it is invalid. -.RE -.TP +: A parse error occurred. +.IP +.nf +\f[C] +Parse errors include unexpected **EOF**, using an invalid character, failing +to find the end of a string or comment, and using a token where it is +invalid. +\f[R] +.fi +.PP \f[B]3\f[R] -A runtime error occurred. -.RS .PP -Runtime errors include assigning an invalid number to \f[B]ibase\f[R], -\f[B]obase\f[R], or \f[B]scale\f[R]; give a bad expression to a -\f[B]read()\f[R] call, calling \f[B]read()\f[R] inside of a -\f[B]read()\f[R] call, type errors, and attempting an operation when the -stack has too few elements. -.RE -.TP +: A runtime error occurred. +.IP +.nf +\f[C] +Runtime errors include assigning an invalid number to **ibase**, **obase**, +or **scale**; give a bad expression to a **read()** call, calling **read()** +inside of a **read()** call, type errors, and attempting an operation when +the stack has too few elements. +\f[R] +.fi +.PP \f[B]4\f[R] -A fatal error occurred. -.RS .PP -Fatal errors include memory allocation errors, I/O errors, failing to -open files, attempting to use files that do not have only ASCII -characters (dc(1) only accepts ASCII characters), attempting to open a -directory as a file, and giving invalid command-line options. -.RE +: A fatal error occurred. +.IP +.nf +\f[C] +Fatal errors include memory allocation errors, I/O errors, failing to open +files, attempting to use files that do not have only ASCII characters (dc(1) +only accepts ASCII characters), attempting to open a directory as a file, +and giving invalid command-line options. +\f[R] +.fi .PP The exit status \f[B]4\f[R] is special; when a fatal error occurs, dc(1) always exits and returns \f[B]4\f[R], no matter what mode dc(1) is in. @@ -1272,7 +1484,7 @@ In interactive mode, dc(1) attempts to recover from errors (see the .SH TTY MODE .PP If \f[B]stdin\f[R], \f[B]stdout\f[R], and \f[B]stderr\f[R] are all -connected to a TTY, dc(1) turns on \[lq]TTY mode.\[rq] +connected to a TTY, dc(1) turns on \[dq]TTY mode.\[dq] .PP TTY mode is required for history to be enabled (see the \f[B]COMMAND LINE HISTORY\f[R] section). @@ -1292,7 +1504,7 @@ If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[R] section), it will reset (see the \f[B]RESET\f[R] section). Otherwise, it will clean up and exit. .PP -Note that \[lq]current input\[rq] can mean one of two things. +Note that \[dq]current input\[dq] can mean one of two things. If dc(1) is processing input from \f[B]stdin\f[R] in TTY mode, it will ask for more input. If dc(1) is processing input from a file in TTY mode, it will stop diff --git a/manuals/dc/P.1.md b/manuals/dc/P.1.md index 0101b68fb872..ccb71bf549fa 100644 --- a/manuals/dc/P.1.md +++ b/manuals/dc/P.1.md @@ -34,7 +34,7 @@ dc - arbitrary-precision decimal reverse-Polish notation calculator # SYNOPSIS -**dc** [**-hiPvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] +**dc** [**-hiPRvVx**] [**-\-version**] [**-\-help**] [**-\-interactive**] [**-\-no-prompt**] [**-\-no-read-prompt**] [**-\-extended-register**] [**-e** *expr*] [**-\-expression**=*expr*...] [**-f** *file*...] [**-\-file**=*file*...] [*file*...] # DESCRIPTION @@ -80,6 +80,12 @@ The following are the options that dc(1) accepts. **-P**, **-\-no-prompt** +: This option is a no-op. + + This is a **non-portable extension**. + +**-R**, **-\-no-read-prompt** + : This option is a no-op. This is a **non-portable extension**. @@ -553,25 +559,25 @@ These commands control the stack. These commands control registers (see the **REGISTERS** section). -**s***r* +**s**_r_ : Pops the value off the top of the stack and stores it into register *r*. -**l***r* +**l**_r_ : Copies the value in register *r* and pushes it onto the stack. This does not alter the contents of *r*. -**S***r* +**S**_r_ : Pops the value off the top of the (main) stack and pushes it onto the stack of register *r*. The previous value of the register becomes inaccessible. -**L***r* +**L**_r_ : Pops the value off the top of the stack for register *r* and push it onto the main stack. The previous value in the stack for register *r*, if any, is - now accessible via the **l***r* command. + now accessible via the **l**_r_ command. ## Parameters @@ -720,7 +726,7 @@ will be printed with a newline after and then popped from the stack. This behavior is the norm whenever a macro is executed, whether by this command or by the conditional execution commands below. -**\>***r* +**\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is greater than the second, then the contents of register @@ -732,7 +738,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**>***r***e***s* +**>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -741,7 +747,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\>***r* +**!\>**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not greater than the second (less than or equal to), then @@ -750,7 +756,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\>***r***e***s* +**!\>**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -759,7 +765,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**\<***r* +**\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is less than the second, then the contents of register *r* @@ -768,7 +774,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**\<***r***e***s* +**\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -777,7 +783,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!\<***r* +**!\<**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not less than the second (greater than or equal to), then @@ -786,7 +792,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!\<***r***e***s* +**!\<**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -795,7 +801,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**=***r* +**=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is equal to the second, then the contents of register *r* @@ -804,7 +810,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**=***r***e***s* +**=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -813,7 +819,7 @@ will be printed with a newline after and then popped from the stack. This is a **non-portable extension**. -**!=***r* +**!=**_r_ : Pops two values off of the stack that must be numbers and compares them. If the first value is not equal to the second, then the contents of register @@ -822,7 +828,7 @@ will be printed with a newline after and then popped from the stack. If either or both of the values are not numbers, dc(1) will raise an error and reset (see the **RESET** section). -**!=***r***e***s* +**!=**_r_**e**_s_ : Like the above, but will execute register *s* if the comparison fails. @@ -878,12 +884,12 @@ These commands query status of the stack or its top value. These commands manipulate arrays. -**:***r* +**:**_r_ : Pops the top two values off of the stack. The second value will be stored in the array *r* (see the **REGISTERS** section), indexed by the first value. -**;***r* +**;**_r_ : Pops the value on top of the stack and uses it as an index into the array *r*. The selected value is then pushed onto the stack. diff --git a/manuals/header_bc.txt b/manuals/header_bc.txt index e07d2e79a1ce..594138f68956 100644 --- a/manuals/header_bc.txt +++ b/manuals/header_bc.txt @@ -1 +1 @@ -.TH "BC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "BC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" diff --git a/manuals/header_bcl.txt b/manuals/header_bcl.txt index 5933f01f2732..26bbefa1b61e 100644 --- a/manuals/header_bcl.txt +++ b/manuals/header_bcl.txt @@ -1 +1 @@ -.TH "BCL" "3" "March 2021" "Gavin D. Howard" "Libraries Manual" +.TH "BCL" "3" "April 2021" "Gavin D. Howard" "Libraries Manual" diff --git a/manuals/header_dc.txt b/manuals/header_dc.txt index 227aac310a0e..e1e2c98373f5 100644 --- a/manuals/header_dc.txt +++ b/manuals/header_dc.txt @@ -1 +1 @@ -.TH "DC" "1" "March 2021" "Gavin D. Howard" "General Commands Manual" +.TH "DC" "1" "April 2021" "Gavin D. Howard" "General Commands Manual" diff --git a/release.sh b/release.sh index 902f26ef4d33..e30875f10c17 100755 --- a/release.sh +++ b/release.sh @@ -30,6 +30,7 @@ usage() { printf 'usage: %s [run_tests] [generate_tests] [test_with_clang] [test_with_gcc] \n' "$script" printf ' [run_sanitizers] [run_valgrind] [run_64_bit] [run_gen_script]\n' + printf ' [test_c11] [test_128_bit]\n' exit 1 } @@ -216,8 +217,10 @@ runconfigseries() { if [ "$run_64_bit" -ne 0 ]; then - runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ - "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" + if [ "$test_128_bit" -ne 0 ]; then + runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ + "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" + fi if [ "$run_gen_script" -ne 0 ]; then runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ @@ -307,7 +310,10 @@ runtests() { shift runtestseries "-std=c99 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" - runtestseries "-std=c11 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" + + if [ "$test_c11" -ne 0 ]; then + runtestseries "-std=c11 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" + fi } karatsuba() { @@ -498,6 +504,20 @@ else run_gen_script=0 fi +if [ "$#" -gt 0 ]; then + test_c11="$1" + shift +else + test_c11=0 +fi + +if [ "$#" -gt 0 ]; then + test_128_bit="$1" + shift +else + test_128_bit=0 +fi + if [ "$run_64_bit" -ne 0 ]; then bits=64 else @@ -523,8 +543,6 @@ header "Running math library under --standard" printf 'quit\n' | bin/bc -ls -version=$(make version) - do_make clean_tests if [ "$test_with_clang" -ne 0 ]; then @@ -573,8 +591,9 @@ if [ "$run_tests" -ne 0 ]; then printf '\n' printf 'Then run the GitHub release script as follows:\n' printf '\n' - printf ' %s release.sh RELEASE.md\\\n' "$version" - printf ' tests/afl.py tests/radamsa.sh tests/radamsa.txt tests/randmath.py \\\n' + printf ' .gitignore .gitattributes\\\n' + printf ' manpage.sh release.sh RELEASE.md tests/afl.py\\\n' + printf ' tests/radamsa.sh tests/radamsa.txt tests/randmath.py\\\n' printf ' tests/fuzzing/ tests/bc/scripts/timeconst.bc\n' fi diff --git a/src/args.c b/src/args.c index 9c26b7c18790..c764ca837e2a 100644 --- a/src/args.c +++ b/src/args.c @@ -39,7 +39,9 @@ #include #include +#ifndef _WIN32 #include +#endif // _WIN32 #include #include @@ -53,6 +55,7 @@ static const BcOptLong bc_args_lopt[] = { { "help", BC_OPT_NONE, 'h' }, { "interactive", BC_OPT_NONE, 'i' }, { "no-prompt", BC_OPT_NONE, 'P' }, + { "no-read-prompt", BC_OPT_NONE, 'R' }, #if BC_ENABLED { "global-stacks", BC_OPT_BC_ONLY, 'g' }, { "mathlib", BC_OPT_BC_ONLY, 'l' }, @@ -144,6 +147,12 @@ void bc_args(int argc, char *argv[], bool exit_exprs) { break; } + case 'R': + { + vm.flags |= BC_FLAG_R; + break; + } + #if BC_ENABLED case 'g': { diff --git a/src/data.c b/src/data.c index 08b8b19b5692..7611d4f05171 100644 --- a/src/data.c +++ b/src/data.c @@ -172,6 +172,12 @@ const char* const bc_err_msgs[] = { }; +#if BC_ENABLE_HISTORY +const BcFlushType bc_flush_none = BC_FLUSH_NO_EXTRAS_NO_CLEAR; +const BcFlushType bc_flush_err = BC_FLUSH_NO_EXTRAS_CLEAR; +const BcFlushType bc_flush_save = BC_FLUSH_SAVE_EXTRAS_CLEAR; +#endif // BC_ENABLE_HISTORY + #if BC_ENABLE_HISTORY const char *bc_history_bad_terms[] = { "dumb", "cons25", "emacs", NULL }; diff --git a/src/file.c b/src/file.c index e69092f6207a..fb904423f1b6 100644 --- a/src/file.c +++ b/src/file.c @@ -36,7 +36,10 @@ #include #include #include + +#ifndef _WIN32 #include +#endif // _WIN32 #include #include @@ -82,11 +85,32 @@ static BcStatus bc_file_output(int fd, const char *buf, size_t n) { return BC_STATUS_SUCCESS; } -BcStatus bc_file_flushErr(BcFile *restrict f) { - +BcStatus bc_file_flushErr(BcFile *restrict f, BcFlushType type) +{ BcStatus s; if (f->len) { + +#if BC_ENABLE_HISTORY + if (BC_TTY) { + if (f->buf[f->len - 1] != '\n' && + (type == BC_FLUSH_SAVE_EXTRAS_CLEAR || + type == BC_FLUSH_SAVE_EXTRAS_NO_CLEAR)) + { + size_t i; + + for (i = f->len - 2; i < f->len && f->buf[i] != '\n'; --i); + + i += 1; + + bc_vec_string(&vm.history.extras, f->len - i, f->buf + i); + } + else if (type >= BC_FLUSH_NO_EXTRAS_CLEAR) { + bc_vec_popAll(&vm.history.extras); + } + } +#endif // BC_ENABLE_HISTORY + s = bc_file_output(f->fd, f->buf, f->len); f->len = 0; } @@ -95,9 +119,9 @@ BcStatus bc_file_flushErr(BcFile *restrict f) { return s; } -void bc_file_flush(BcFile *restrict f) { +void bc_file_flush(BcFile *restrict f, BcFlushType type) { - BcStatus s = bc_file_flushErr(f); + BcStatus s = bc_file_flushErr(f, type); if (BC_ERR(s)) { @@ -109,10 +133,11 @@ void bc_file_flush(BcFile *restrict f) { } } -void bc_file_write(BcFile *restrict f, const char *buf, size_t n) { - +void bc_file_write(BcFile *restrict f, BcFlushType type, + const char *buf, size_t n) +{ if (n > f->cap - f->len) { - bc_file_flush(f); + bc_file_flush(f, type); assert(!f->len); } @@ -123,8 +148,8 @@ void bc_file_write(BcFile *restrict f, const char *buf, size_t n) { } } -void bc_file_printf(BcFile *restrict f, const char *fmt, ...) { - +void bc_file_printf(BcFile *restrict f, const char *fmt, ...) +{ va_list args; va_start(args, fmt); @@ -144,7 +169,7 @@ void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) { if (percent != ptr) { size_t len = (size_t) (percent - ptr); - bc_file_write(f, ptr, len); + bc_file_write(f, bc_flush_none, ptr, len); } c = percent[1]; @@ -153,13 +178,13 @@ void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) { uchar uc = (uchar) va_arg(args, int); - bc_file_putchar(f, uc); + bc_file_putchar(f, bc_flush_none, uc); } else if (c == 's') { char *s = va_arg(args, char*); - bc_file_puts(f, s); + bc_file_puts(f, bc_flush_none, s); } #if BC_DEBUG_CODE else if (c == 'd') { @@ -167,14 +192,14 @@ void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) { int d = va_arg(args, int); if (d < 0) { - bc_file_putchar(f, '-'); + bc_file_putchar(f, bc_flush_none, '-'); d = -d; } - if (!d) bc_file_putchar(f, '0'); + if (!d) bc_file_putchar(f, bc_flush_none, '0'); else { bc_file_ultoa((unsigned long long) d, buf); - bc_file_puts(f, buf); + bc_file_puts(f, bc_flush_none, buf); } } #endif // BC_DEBUG_CODE @@ -187,25 +212,25 @@ void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) { if (c == 'z') ull = (unsigned long long) va_arg(args, size_t); else ull = (unsigned long long) va_arg(args, unsigned long); - if (!ull) bc_file_putchar(f, '0'); + if (!ull) bc_file_putchar(f, bc_flush_none, '0'); else { bc_file_ultoa(ull, buf); - bc_file_puts(f, buf); + bc_file_puts(f, bc_flush_none, buf); } } ptr = percent + 2 + (c == 'l' || c == 'z'); } - if (ptr[0]) bc_file_puts(f, ptr); + if (ptr[0]) bc_file_puts(f, bc_flush_none, ptr); } -void bc_file_puts(BcFile *restrict f, const char *str) { - bc_file_write(f, str, strlen(str)); +void bc_file_puts(BcFile *restrict f, BcFlushType type, const char *str) { + bc_file_write(f, type, str, strlen(str)); } -void bc_file_putchar(BcFile *restrict f, uchar c) { - if (f->len == f->cap) bc_file_flush(f); +void bc_file_putchar(BcFile *restrict f, BcFlushType type, uchar c) { + if (f->len == f->cap) bc_file_flush(f, type); assert(f->len < f->cap); f->buf[f->len] = (char) c; f->len += 1; @@ -221,5 +246,5 @@ void bc_file_init(BcFile *f, int fd, char *buf, size_t cap) { void bc_file_free(BcFile *f) { BC_SIG_ASSERT_LOCKED; - bc_file_flush(f); + bc_file_flush(f, bc_flush_none); } diff --git a/src/history.c b/src/history.c index 7c4f0ceb0f39..c0d54fe35234 100644 --- a/src/history.c +++ b/src/history.c @@ -505,8 +505,8 @@ static size_t bc_history_cursorPos(void) { size_t cols, rows, i; // Report cursor location. - bc_file_write(&vm.fout, "\x1b[6n", 4); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, "\x1b[6n", 4); + bc_file_flush(&vm.fout, bc_flush_none); // Read the response: ESC [ rows ; cols R. for (i = 0; i < sizeof(buf) - 1; ++i) { @@ -556,15 +556,15 @@ static size_t bc_history_columns(void) { if (BC_ERR(start == SIZE_MAX)) return BC_HIST_DEF_COLS; // Go to right margin and get position. - bc_file_write(&vm.fout, "\x1b[999C", 6); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, "\x1b[999C", 6); + bc_file_flush(&vm.fout, bc_flush_none); cols = bc_history_cursorPos(); if (BC_ERR(cols == SIZE_MAX)) return BC_HIST_DEF_COLS; // Restore position. if (cols > start) { bc_file_printf(&vm.fout, "\x1b[%zuD", cols - start); - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_none); } return cols; @@ -632,7 +632,7 @@ static void bc_history_refresh(BcHistory *h) { char* buf = h->buf.v; size_t colpos, len = BC_HIST_BUF_LEN(h), pos = h->pos; - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_none); while(h->pcol + bc_history_colPos(buf, len, pos) >= h->cols) { @@ -647,24 +647,32 @@ static void bc_history_refresh(BcHistory *h) { len -= bc_history_prevLen(buf, len, NULL); // Cursor to left edge. - bc_file_write(&vm.fout, "\r", 1); + bc_file_write(&vm.fout, bc_flush_none, "\r", 1); + + // Take the extra stuff into account. + if (h->extras.len > 1) { + len += h->extras.len - 1; + pos += h->extras.len - 1; + bc_file_write(&vm.fout, bc_flush_none, h->extras.v, h->extras.len - 1); + } // Write the prompt, if desired. #if BC_ENABLE_PROMPT - if (BC_USE_PROMPT) bc_file_write(&vm.fout, h->prompt, h->plen); + if (BC_USE_PROMPT) + bc_file_write(&vm.fout, bc_flush_none, h->prompt, h->plen); #endif // BC_ENABLE_PROMPT - bc_file_write(&vm.fout, buf, BC_HIST_BUF_LEN(h)); + bc_file_write(&vm.fout, bc_flush_none, buf, BC_HIST_BUF_LEN(h)); // Erase to right. - bc_file_write(&vm.fout, "\x1b[0K", 4); + bc_file_write(&vm.fout, bc_flush_none, "\x1b[0K", 4); // Move cursor to original position. colpos = bc_history_colPos(buf, len, pos) + h->pcol; if (colpos) bc_file_printf(&vm.fout, "\r\x1b[%zuC", colpos); - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_none); } /** @@ -684,7 +692,7 @@ static void bc_history_edit_insert(BcHistory *h, const char *cbuf, size_t clen) h->buf.len += clen - 1; bc_vec_pushByte(&h->buf, '\0'); - len = BC_HIST_BUF_LEN(h); + len = BC_HIST_BUF_LEN(h) + h->extras.len - 1; #if BC_ENABLE_PROMPT colpos = bc_history_promptColLen(h->prompt, h->plen); #endif // BC_ENABLE_PROMPT @@ -693,8 +701,8 @@ static void bc_history_edit_insert(BcHistory *h, const char *cbuf, size_t clen) if (colpos < h->cols) { // Avoid a full update of the line in the trivial case. - bc_file_write(&vm.fout, cbuf, clen); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, cbuf, clen); + bc_file_flush(&vm.fout, bc_flush_none); } else bc_history_refresh(h); } @@ -1102,7 +1110,7 @@ static void bc_history_printCtrl(BcHistory *h, unsigned int c) { bc_vec_pushByte(&h->buf, '\0'); if (c != BC_ACTION_CTRL_C && c != BC_ACTION_CTRL_D) { - bc_file_write(&vm.fout, newline, sizeof(newline) - 1); + bc_file_write(&vm.fout, bc_flush_none, newline, sizeof(newline) - 1); bc_history_refresh(h); } } @@ -1116,6 +1124,11 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) { bc_history_reset(h); + // Don't write the saved output the first time. This is because it has + // already been written to output. In other words, don't uncomment the + // line below or add anything like it. + // bc_file_write(&vm.fout, bc_flush_none, h->extras.v, h->extras.len - 1); + #if BC_ENABLE_PROMPT if (BC_USE_PROMPT) { @@ -1123,8 +1136,8 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) { h->plen = strlen(prompt); h->pcol = bc_history_promptColLen(prompt, h->plen); - bc_file_write(&vm.fout, prompt, h->plen); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, prompt, h->plen); + bc_file_flush(&vm.fout, bc_flush_none); } #endif // BC_ENABLE_PROMPT @@ -1158,8 +1171,8 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) { case BC_ACTION_CTRL_C: { bc_history_printCtrl(h, c); - bc_file_write(&vm.fout, vm.sigmsg, vm.siglen); - bc_file_write(&vm.fout, bc_program_ready_msg, + bc_file_write(&vm.fout, bc_flush_none, vm.sigmsg, vm.siglen); + bc_file_write(&vm.fout, bc_flush_none, bc_program_ready_msg, bc_program_ready_msg_len); bc_history_reset(h); bc_history_refresh(h); @@ -1254,7 +1267,7 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) { // Clear screen. case BC_ACTION_CTRL_L: { - bc_file_write(&vm.fout, "\x1b[H\x1b[2J", 7); + bc_file_write(&vm.fout, bc_flush_none, "\x1b[H\x1b[2J", 7); bc_history_refresh(h); break; } @@ -1302,8 +1315,8 @@ static BcStatus bc_history_raw(BcHistory *h, const char *prompt) { h->stdin_has_data = bc_history_stdinHasData(h); if (!h->stdin_has_data) bc_history_disableRaw(h); - bc_file_write(&vm.fout, "\n", 1); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, "\n", 1); + bc_file_flush(&vm.fout, bc_flush_none); return s; } @@ -1382,6 +1395,7 @@ void bc_history_init(BcHistory *h) { bc_vec_init(&h->buf, sizeof(char), NULL); bc_vec_init(&h->history, sizeof(char*), bc_history_string_free); + bc_vec_init(&h->extras, sizeof(char), NULL); FD_ZERO(&h->rdset); FD_SET(STDIN_FILENO, &h->rdset); @@ -1401,6 +1415,7 @@ void bc_history_free(BcHistory *h) { #ifndef NDEBUG bc_vec_free(&h->buf); bc_vec_free(&h->history); + bc_vec_free(&h->extras); #endif // NDEBUG } @@ -1439,8 +1454,8 @@ void bc_history_printKeyCodes(BcHistory *h) { isprint(c) ? c : '?', (unsigned long) c); // Go left edge manually, we are in raw mode. - bc_vm_putchar('\r'); - bc_file_flush(&vm.fout); + bc_vm_putchar('\r', bc_flush_none); + bc_file_flush(&vm.fout, bc_flush_none); } bc_history_disableRaw(h); diff --git a/src/main.c b/src/main.c index 84a48ff7e301..afe2fd8bb2ac 100644 --- a/src/main.c +++ b/src/main.c @@ -38,10 +38,14 @@ #include #include + +#ifndef _WIN32 #include +#endif // _WIN32 #include +#include #include #include #include @@ -54,7 +58,7 @@ int main(int argc, char *argv[]) { vm.locale = setlocale(LC_ALL, ""); - name = strrchr(argv[0], '/'); + name = strrchr(argv[0], BC_FILE_SEP); vm.name = (name == NULL) ? argv[0] : name + 1; if (strlen(vm.name) > len) vm.name += len; diff --git a/src/num.c b/src/num.c index 6131034ac535..5b84c2b88600 100644 --- a/src/num.c +++ b/src/num.c @@ -1389,7 +1389,7 @@ static void bc_num_right(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) { #endif // BC_ENABLE_EXTRA_MATH static void bc_num_binary(BcNum *a, BcNum *b, BcNum *c, size_t scale, - BcNumBinaryOp op, size_t req) + BcNumBinOp op, size_t req) { BcNum *ptr_a, *ptr_b, num2; bool init = false; @@ -1655,15 +1655,15 @@ static void bc_num_parseBase(BcNum *restrict n, const char *restrict val, static inline void bc_num_printNewline(void) { #if !BC_ENABLE_LIBRARY if (vm.nchars >= vm.line_len - 1) { - bc_vm_putchar('\\'); - bc_vm_putchar('\n'); + bc_vm_putchar('\\', bc_flush_none); + bc_vm_putchar('\n', bc_flush_err); } #endif // !BC_ENABLE_LIBRARY } static void bc_num_putchar(int c) { if (c != '\n') bc_num_printNewline(); - bc_vm_putchar(c); + bc_vm_putchar(c, bc_flush_save); } #if DC_ENABLED && !BC_ENABLE_LIBRARY @@ -1671,7 +1671,7 @@ static void bc_num_printChar(size_t n, size_t len, bool rdx) { BC_UNUSED(rdx); BC_UNUSED(len); assert(len == 1); - bc_vm_putchar((uchar) n); + bc_vm_putchar((uchar) n, bc_flush_save); } #endif // DC_ENABLED && !BC_ENABLE_LIBRARY @@ -2908,11 +2908,11 @@ void bc_num_modexp(BcNum *a, BcNum *b, BcNum *c, BcNum *restrict d) { #if BC_DEBUG_CODE void bc_num_printDebug(const BcNum *n, const char *name, bool emptyline) { - bc_file_puts(&vm.fout, name); - bc_file_puts(&vm.fout, ": "); + bc_file_puts(&vm.fout, bc_flush_none, name); + bc_file_puts(&vm.fout, bc_flush_none, ": "); bc_num_printDecimal(n); - bc_file_putchar(&vm.fout, '\n'); - if (emptyline) bc_file_putchar(&vm.fout, '\n'); + bc_file_putchar(&vm.fout, bc_flush_err, '\n'); + if (emptyline) bc_file_putchar(&vm.fout, bc_flush_err, '\n'); vm.nchars = 0; } @@ -2923,13 +2923,13 @@ void bc_num_printDigs(const BcDig *n, size_t len, bool emptyline) { for (i = len - 1; i < len; --i) bc_file_printf(&vm.fout, " %lu", (unsigned long) n[i]); - bc_file_putchar(&vm.fout, '\n'); - if (emptyline) bc_file_putchar(&vm.fout, '\n'); + bc_file_putchar(&vm.fout, bc_flush_err, '\n'); + if (emptyline) bc_file_putchar(&vm.fout, bc_flush_err, '\n'); vm.nchars = 0; } void bc_num_printWithDigs(const BcNum *n, const char *name, bool emptyline) { - bc_file_puts(&vm.fout, name); + bc_file_puts(&vm.fout, bc_flush_none, name); bc_file_printf(&vm.fout, " len: %zu, rdx: %zu, scale: %zu\n", name, n->len, BC_NUM_RDX_VAL(n), n->scale); bc_num_printDigs(n->num, n->len, emptyline); @@ -2944,7 +2944,8 @@ void bc_num_dump(const char *varname, const BcNum *n) { for (i = n->len - 1; i < n->len; --i) { - if (i + 1 == BC_NUM_RDX_VAL(n)) bc_file_puts(&vm.ferr, ". "); + if (i + 1 == BC_NUM_RDX_VAL(n)) + bc_file_puts(&vm.ferr, bc_flush_none, ". "); if (scale / BC_BASE_DIGS != BC_NUM_RDX_VAL(n) - i - 1) bc_file_printf(&vm.ferr, "%lu ", (unsigned long) n->num[i]); @@ -2967,5 +2968,7 @@ void bc_num_dump(const char *varname, const BcNum *n) { bc_file_printf(&vm.ferr, "(%zu | %zu.%zu / %zu) %lu\n", n->scale, n->len, BC_NUM_RDX_VAL(n), n->cap, (unsigned long) (void*) n->num); + + bc_file_flush(&vm.ferr, bc_flush_err); } #endif // BC_DEBUG_CODE diff --git a/src/program.c b/src/program.c index 6ab794736f79..82735083bd03 100644 --- a/src/program.c +++ b/src/program.c @@ -456,7 +456,9 @@ static void bc_program_read(BcProgram *p) { bc_lex_file(&parse.l, bc_program_stdin_name); bc_vec_popAll(&f->code); - s = bc_read_line(&buf, BC_IS_BC ? "read> " : "?> "); + if (BC_R) s = bc_read_line(&buf, ""); + else s = bc_read_line(&buf, BC_IS_BC ? "read> " : "?> "); + if (s == BC_STATUS_EOF) bc_vm_err(BC_ERR_EXEC_READ_EXPR); bc_parse_text(&parse, buf.v); @@ -512,7 +514,7 @@ static void bc_program_printChars(const char *str) { const char *nl; size_t len = vm.nchars + strlen(str); - bc_file_puts(&vm.fout, str); + bc_file_puts(&vm.fout, bc_flush_save, str); nl = strrchr(str, '\n'); if (nl != NULL) len = strlen(nl + 1); @@ -526,7 +528,7 @@ static void bc_program_printString(const char *restrict str) { #if DC_ENABLED if (!len && BC_IS_DC) { - bc_vm_putchar('\0'); + bc_vm_putchar('\0', bc_flush_save); return; } #endif // DC_ENABLED @@ -549,11 +551,11 @@ static void bc_program_printString(const char *restrict str) { else { // Just print the backslash. The following // character will be printed later. - bc_vm_putchar('\\'); + bc_vm_putchar('\\', bc_flush_save); } } - bc_vm_putchar(c); + bc_vm_putchar(c, bc_flush_save); } } @@ -598,13 +600,14 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { size_t i = (r->t == BC_RESULT_STR) ? r->d.loc.loc : n->scale; - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_save); str = *((char**) bc_vec_item(p->strs, i)); if (inst == BC_INST_PRINT_STR) bc_program_printChars(str); else { bc_program_printString(str); - if (inst == BC_INST_PRINT) bc_vm_putchar('\n'); + if (inst == BC_INST_PRINT) + bc_vm_putchar('\n', bc_flush_err); } } @@ -1440,6 +1443,8 @@ static void bc_program_printStream(BcProgram *p) { size_t idx = (r->t == BC_RESULT_STR) ? r->d.loc.loc : n->scale; bc_program_printChars(*((char**) bc_vec_item(p->strs, idx))); } + + bc_vec_pop(&p->results); } static void bc_program_nquit(BcProgram *p, uchar inst) { @@ -1463,7 +1468,7 @@ static void bc_program_nquit(BcProgram *p, uchar inst) { for (i = 0; val && i < p->tail_calls.len; ++i) { size_t calls = *((size_t*) bc_vec_item_rev(&p->tail_calls, i)) + 1; if (calls >= val) val = 0; - else val -= calls; + else val -= (BcBigDig) calls; } if (i == p->stack.len) { @@ -1807,8 +1812,9 @@ void bc_program_reset(BcProgram *p) { memset(ip, 0, sizeof(BcInstPtr)); if (vm.sig) { - bc_file_write(&vm.fout, bc_program_ready_msg, bc_program_ready_msg_len); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, bc_program_ready_msg, + bc_program_ready_msg_len); + bc_file_flush(&vm.fout, bc_flush_err); vm.sig = 0; } } @@ -1930,7 +1936,7 @@ void bc_program_exec(BcProgram *p) { { // We want to flush output before // this in case there is a prompt. - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_save); bc_program_read(p); @@ -2264,9 +2270,9 @@ void bc_program_exec(BcProgram *p) { #if BC_DEBUG_CODE #if BC_ENABLED && DC_ENABLED void bc_program_printStackDebug(BcProgram *p) { - bc_file_puts(&vm.fout, "-------------- Stack ----------\n"); + bc_file_puts(&vm.fout, bc_flush_err, "-------------- Stack ----------\n"); bc_program_printStack(p); - bc_file_puts(&vm.fout, "-------------- Stack End ------\n"); + bc_file_puts(&vm.fout, bc_flush_err, "-------------- Stack End ------\n"); } static void bc_program_printIndex(const char *restrict code, @@ -2320,7 +2326,7 @@ void bc_program_printInst(const BcProgram *p, const char *restrict code, if (inst == BC_INST_CALL) bc_program_printIndex(code, bgn); } - bc_vm_putchar('\n'); + bc_vm_putchar('\n', bc_flush_err); } void bc_program_code(const BcProgram* p) { @@ -2340,7 +2346,7 @@ void bc_program_code(const BcProgram* p) { bc_vm_printf("func[%zu]:\n", ip.func); while (ip.idx < f->code.len) bc_program_printInst(p, code, &ip.idx); - bc_file_puts(&vm.fout, "\n\n"); + bc_file_puts(&vm.fout, bc_flush_err, "\n\n"); } } #endif // BC_ENABLED && DC_ENABLED diff --git a/src/rand.c b/src/rand.c index 6b2ec7bdb30f..886f7a6bd471 100644 --- a/src/rand.c +++ b/src/rand.c @@ -44,7 +44,13 @@ #include #include #include + +#ifndef _WIN32 #include +#else // _WIN32 +#include +#include +#endif // _WIN32 #include #include @@ -140,7 +146,8 @@ static void bc_rand_copy(BcRNGData *d, BcRNGData *s) { else if (!BC_RAND_NOTMODIFIED(s)) bc_rand_clearModified(d); } -static ulong bc_rand_frand(void *ptr) { +#ifndef _WIN32 +static ulong bc_rand_frand(void* ptr) { ulong buf[1]; int fd; @@ -148,14 +155,31 @@ static ulong bc_rand_frand(void *ptr) { assert(ptr != NULL); - fd = *((int*) ptr); + fd = *((int*)ptr); nread = read(fd, buf, sizeof(ulong)); if (BC_ERR(nread != sizeof(ulong))) bc_vm_fatalError(BC_ERR_FATAL_IO_ERR); - return *((ulong*) buf); + return *((ulong*)buf); } +#else // _WIN32 +static ulong bc_rand_winrand(void* ptr) { + + ulong buf[1]; + NTSTATUS s; + + BC_UNUSED(ptr); + + buf[0] = 0; + + s = BCryptGenRandom(NULL, (char*) buf, sizeof(ulong), BCRYPT_USE_SYSTEM_PREFERRED_RNG); + + if (BC_ERR(!BCRYPT_SUCCESS(s))) buf[0] = 0; + + return buf[0]; +} +#endif // _WIN32 static ulong bc_rand_rand(void *ptr) { @@ -252,10 +276,11 @@ static void bc_rand_seedZeroes(BcRNG *r, BcRNGData *rng, size_t idx) { void bc_rand_srand(BcRNGData *rng) { - int fd; + int fd = 0; BC_SIG_LOCK; +#ifndef _WIN32 fd = open("/dev/urandom", O_RDONLY); if (BC_NO_ERR(fd >= 0)) { @@ -271,6 +296,9 @@ void bc_rand_srand(BcRNGData *rng) { close(fd); } } +#else // _WIN32 + bc_rand_fill(rng, bc_rand_winrand, NULL); +#endif // _WIN32 while (BC_ERR(BC_RAND_ZERO(rng))) bc_rand_fill(rng, bc_rand_rand, NULL); diff --git a/src/read.c b/src/read.c index e593b3c2dedd..43e65b65b345 100644 --- a/src/read.c +++ b/src/read.c @@ -43,13 +43,30 @@ #include #include + +#ifndef _WIN32 #include +#endif // _WIN32 #include #include #include #include +static int bc_read_open(const char* path, int mode) { + + int fd; + +#ifndef _WIN32 + fd = open(path, mode); +#else // _WIN32 + fd = -1; + open(&fd, path, mode); +#endif + + return fd; +} + static bool bc_read_binary(const char *buf, size_t size) { size_t i; @@ -100,8 +117,8 @@ BcStatus bc_read_chars(BcVec *vec, const char *prompt) { #if BC_ENABLE_PROMPT if (BC_USE_PROMPT) { - bc_file_puts(&vm.fout, prompt); - bc_file_flush(&vm.fout); + bc_file_puts(&vm.fout, bc_flush_none, prompt); + bc_file_flush(&vm.fout, bc_flush_none); } #endif // BC_ENABLE_PROMPT @@ -132,9 +149,10 @@ BcStatus bc_read_chars(BcVec *vec, const char *prompt) { vm.status = (sig_atomic_t) BC_STATUS_SUCCESS; #if BC_ENABLE_PROMPT - if (BC_USE_PROMPT) bc_file_puts(&vm.fout, prompt); + if (BC_USE_PROMPT) + bc_file_puts(&vm.fout, bc_flush_none, prompt); #endif // BC_ENABLE_PROMPT - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_none); BC_SIG_UNLOCK; @@ -193,7 +211,8 @@ void bc_read_file(const char *path, char **buf) { assert(path != NULL); - fd = open(path, O_RDONLY); + fd = bc_read_open(path, O_RDONLY); + if (BC_ERR(fd < 0)) bc_vm_verr(BC_ERR_FATAL_FILE_ERR, path); if (BC_ERR(fstat(fd, &pstat) == -1)) goto malloc_err; diff --git a/src/vm.c b/src/vm.c index 87036c7b5c91..e7ee8d35ba54 100644 --- a/src/vm.c +++ b/src/vm.c @@ -56,6 +56,7 @@ #endif // _WIN32 +#include #include #include #include @@ -76,10 +77,10 @@ BC_NORETURN void bc_vm_jmp(void) { BC_SIG_MAYLOCK; #if BC_DEBUG_CODE - bc_file_puts(&vm.ferr, "Longjmp: "); - bc_file_puts(&vm.ferr, f); - bc_file_putchar(&vm.ferr, '\n'); - bc_file_flush(&vm.ferr); + bc_file_puts(&vm.ferr, bc_flush_none, "Longjmp: "); + bc_file_puts(&vm.ferr, bc_flush_none, f); + bc_file_putchar(&vm.ferr, bc_flush_none, '\n'); + bc_file_flush(&vm.ferr, bc_flush_none); #endif // BC_DEBUG_CODE #ifndef NDEBUG @@ -119,22 +120,47 @@ static void bc_vm_sig(int sig) { if (!vm.sig_lock) BC_VM_JMP; } +static void bc_vm_sigaction(void) { +#ifndef _WIN32 + + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + sa.sa_handler = bc_vm_sig; + sa.sa_flags = SA_NODEFER; + + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + +#if BC_ENABLE_HISTORY + if (BC_TTY) sigaction(SIGHUP, &sa, NULL); +#endif // BC_ENABLE_HISTORY + +#else // _WIN32 + + signal(SIGTERM, bc_vm_sig); + +#endif // _WIN32 +} + void bc_vm_info(const char* const help) { BC_SIG_ASSERT_LOCKED; - bc_file_puts(&vm.fout, vm.name); - bc_file_putchar(&vm.fout, ' '); - bc_file_puts(&vm.fout, BC_VERSION); - bc_file_putchar(&vm.fout, '\n'); - bc_file_puts(&vm.fout, bc_copyright); + bc_file_puts(&vm.fout, bc_flush_none, vm.name); + bc_file_putchar(&vm.fout, bc_flush_none, ' '); + bc_file_puts(&vm.fout, bc_flush_none, BC_VERSION); + bc_file_putchar(&vm.fout, bc_flush_none, '\n'); + bc_file_puts(&vm.fout, bc_flush_none, bc_copyright); if (help) { - bc_file_putchar(&vm.fout, '\n'); - bc_file_printf(&vm.fout, help, vm.name, vm.name); + bc_file_putchar(&vm.fout, bc_flush_none, '\n'); + bc_file_printf(&vm.fout, help, vm.name, vm.name, + BC_VERSION, BC_BUILD_TYPE); } - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_err); } #endif // !BC_ENABLE_LIBRARY @@ -192,7 +218,7 @@ void bc_vm_handleError(BcErr e, size_t line, ...) { BC_SIG_TRYLOCK(lock); // Make sure all of stdout is written first. - s = bc_file_flushErr(&vm.fout); + s = bc_file_flushErr(&vm.fout, bc_flush_err); if (BC_ERR(s == BC_STATUS_ERROR_FATAL)) { vm.status = (sig_atomic_t) s; @@ -200,9 +226,9 @@ void bc_vm_handleError(BcErr e, size_t line, ...) { } va_start(args, line); - bc_file_putchar(&vm.ferr, '\n'); - bc_file_puts(&vm.ferr, err_type); - bc_file_putchar(&vm.ferr, ' '); + bc_file_putchar(&vm.ferr, bc_flush_none, '\n'); + bc_file_puts(&vm.ferr, bc_flush_none, err_type); + bc_file_putchar(&vm.ferr, bc_flush_none, ' '); bc_file_vprintf(&vm.ferr, vm.err_msgs[e], args); va_end(args); @@ -211,8 +237,8 @@ void bc_vm_handleError(BcErr e, size_t line, ...) { // This is the condition for parsing vs runtime. // If line is not 0, it is parsing. if (line) { - bc_file_puts(&vm.ferr, "\n "); - bc_file_puts(&vm.ferr, vm.file); + bc_file_puts(&vm.ferr, bc_flush_none, "\n "); + bc_file_puts(&vm.ferr, bc_flush_none, vm.file); bc_file_printf(&vm.ferr, bc_err_line, line); } else { @@ -220,24 +246,24 @@ void bc_vm_handleError(BcErr e, size_t line, ...) { BcInstPtr *ip = bc_vec_item_rev(&vm.prog.stack, 0); BcFunc *f = bc_vec_item(&vm.prog.fns, ip->func); - bc_file_puts(&vm.ferr, "\n "); - bc_file_puts(&vm.ferr, vm.func_header); - bc_file_putchar(&vm.ferr, ' '); - bc_file_puts(&vm.ferr, f->name); + bc_file_puts(&vm.ferr, bc_flush_none, "\n "); + bc_file_puts(&vm.ferr, bc_flush_none, vm.func_header); + bc_file_putchar(&vm.ferr, bc_flush_none, ' '); + bc_file_puts(&vm.ferr, bc_flush_none, f->name); #if BC_ENABLED if (BC_IS_BC && ip->func != BC_PROG_MAIN && ip->func != BC_PROG_READ) { - bc_file_puts(&vm.ferr, "()"); + bc_file_puts(&vm.ferr, bc_flush_none, "()"); } #endif // BC_ENABLED } } - bc_file_puts(&vm.ferr, "\n\n"); + bc_file_puts(&vm.ferr, bc_flush_none, "\n\n"); - s = bc_file_flushErr(&vm.ferr); + s = bc_file_flushErr(&vm.ferr, bc_flush_err); #if !BC_ENABLE_MEMCHECK // Because this function is called by a BC_NORETURN function when fatal @@ -260,14 +286,19 @@ void bc_vm_handleError(BcErr e, size_t line, ...) { static void bc_vm_envArgs(const char* const env_args_name) { - char *env_args = getenv(env_args_name), *buf, *start; + char *env_args = bc_vm_getenv(env_args_name), *buf, *start; char instr = '\0'; BC_SIG_ASSERT_LOCKED; if (env_args == NULL) return; + // Windows already allocates, so we don't need to. +#ifndef _WIN32 start = buf = vm.env_args_buffer = bc_vm_strdup(env_args); +#else // _WIN32 + start = buf = vm.env_args_buffer = env_args; +#endif // _WIN32 assert(buf != NULL); @@ -320,7 +351,7 @@ static void bc_vm_envArgs(const char* const env_args_name) { static size_t bc_vm_envLen(const char *var) { - char *lenv = getenv(var); + char *lenv = bc_vm_getenv(var); size_t i, len = BC_NUM_PRINT_WIDTH; int num; @@ -336,6 +367,8 @@ static size_t bc_vm_envLen(const char *var) { } else len = BC_NUM_PRINT_WIDTH; + bc_vm_getenvFree(lenv); + return len; } #endif // BC_ENABLE_LIBRARY @@ -455,15 +488,35 @@ void bc_vm_printf(const char *fmt, ...) { } #endif // !BC_ENABLE_LIBRARY -void bc_vm_putchar(int c) { +void bc_vm_putchar(int c, BcFlushType type) { #if BC_ENABLE_LIBRARY bc_vec_pushByte(&vm.out, (uchar) c); #else // BC_ENABLE_LIBRARY - bc_file_putchar(&vm.fout, (uchar) c); + bc_file_putchar(&vm.fout, type, (uchar) c); vm.nchars = (c == '\n' ? 0 : vm.nchars + 1); #endif // BC_ENABLE_LIBRARY } +char* bc_vm_getenv(const char* var) { + + char* ret; + +#ifndef _WIN32 + ret = getenv(var); +#else // _WIN32 + _dupenv_s(&ret, NULL, var); +#endif // _WIN32 + + return ret; +} + +void bc_vm_getenvFree(char* var) { + BC_UNUSED(var); +#ifdef _WIN32 + free(var); +#endif // _WIN32 +} + #if !BC_ENABLE_LIBRARY static void bc_vm_clean(void) { @@ -531,7 +584,7 @@ static void bc_vm_process(const char *text) { assert(BC_IS_DC || vm.prog.results.len == 0); - if (BC_I) bc_file_flush(&vm.fout); + if (BC_I) bc_file_flush(&vm.fout, bc_flush_save); } while (vm.prs.l.t != BC_LEX_EOF); } @@ -853,7 +906,6 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len, const char* const env_args) { int ttyin, ttyout, ttyerr; - struct sigaction sa; BC_SIG_ASSERT_LOCKED; @@ -865,17 +917,7 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len, vm.flags |= (ttyin != 0 && ttyout != 0 && ttyerr != 0) ? BC_FLAG_TTY : 0; vm.flags |= ttyin && ttyout ? BC_FLAG_I : 0; - sigemptyset(&sa.sa_mask); - sa.sa_handler = bc_vm_sig; - sa.sa_flags = SA_NODEFER; - - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGQUIT, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - -#if BC_ENABLE_HISTORY - if (BC_TTY) sigaction(SIGHUP, &sa, NULL); -#endif // BC_ENABLE_HISTORY + bc_vm_sigaction(); bc_vm_init(); @@ -901,7 +943,11 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len, #endif // BC_ENABLE_HISTORY #if BC_ENABLED - if (BC_IS_BC) vm.flags |= BC_FLAG_S * (getenv("POSIXLY_CORRECT") != NULL); + if (BC_IS_BC) { + char* var = bc_vm_getenv("POSIXLY_CORRECT"); + vm.flags |= BC_FLAG_S * (var != NULL); + bc_vm_getenvFree(var); + } #endif // BC_ENABLED bc_vm_envArgs(env_args); diff --git a/tests/dc/scripts/easter.sh b/tests/dc/scripts/easter.sh new file mode 100644 index 000000000000..dd030e4024d0 --- /dev/null +++ b/tests/dc/scripts/easter.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +if test $# -lt 2 +then + echo usage: $0 dc_exec year + exit 1 +fi + +dc_exec="$1" +shift + +year="$1" +shift + +echo $year ' +[ + ddsf + [ + lfp + [too early + ]P + q + ]s@ + 1583>@ + ddd19%1+sg100/1+d3*4/12-sx8*5+25/5-sz5*4/lx-10-sdlg11*20+lz+lx-30% + d + [30+]s@ + 0>@d + [ + [1+]s@ + lg11<@ + ]s@ + 25=@d + [1+]s@ + 24=@se44le-d + [30+]s@ + 21>@dld+7%-7+ + [March ]sm + d + [ + 31- + [April ]sm + ]s@ + 31<@psnlmPpsn1z>p +]sp +lpx' | "$dc_exec" | tr '\012' ' ' +echo '' diff --git a/tests/other.sh b/tests/other.sh index 8c56e25d2395..d2ef4f6d0694 100755 --- a/tests/other.sh +++ b/tests/other.sh @@ -118,6 +118,9 @@ if [ "$d" = "bc" ]; then err="$?" checktest_retcode "$d" "$?" "environment var" + + printf 'pass\n' + else export DC_ENV_ARGS="'-x'" @@ -130,9 +133,39 @@ else "$exe" -e 4pR "$@" > /dev/null checktest_retcode "$d" "$?" "environment var" -fi -printf 'pass\n' + printf 'pass\n' + + set +e + + printf 'three\n' | head -c3 > /dev/null + err=$? + + if [ "$err" -eq 0 ]; then + + printf 'Running dc Easter script...' + + easter_res="$testdir/dc_outputs/easter.txt" + easter_out="$testdir/dc_outputs/easter_results.txt" + + outdir=$(dirname "$easter_out") + + if [ ! -d "$outdir" ]; then + mkdir -p "$outdir" + fi + + printf '4 April 2021\n' > "$easter_res" + + "$testdir/dc/scripts/easter.sh" "$exe" 2021 | head -c12 > "$easter_out" + printf '\n' >> "$easter_out" + err="$?" + + checktest "$d" "$err" "Easter script" "$easter_res" "$easter_out" + + printf 'pass\n' + fi + +fi out1="$testdir/../.log_$d.txt" out2="$testdir/../.log_${d}_test.txt"